technion/libscrypt

can not be linked together with openssl

Closed this issue · 2 comments

Some of the sha256 functions are also defined in openssl library.
So there is an "already defined in" error during linking.
Here is a patch to rename the functions:

diff --git a/crypto_scrypt-nosse.c b/crypto_scrypt-nosse.c
index 6d183ae..f54e42e 100644
--- a/crypto_scrypt-nosse.c
+++ b/crypto_scrypt-nosse.c
@@ -307,7 +307,7 @@ libscrypt_scrypt(const uint8_t * passwd, size_t passwdlen,
 #endif

    /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
-   PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);
+   libscrypt_PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);

    /* 2: for i = 0 to p - 1 do */
    for (i = 0; i < p; i++) {
@@ -316,7 +316,7 @@ libscrypt_scrypt(const uint8_t * passwd, size_t passwdlen,
    }

    /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
-   PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);
+   libscrypt_PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);

    /* Free memory. */
 #ifdef MAP_ANON
diff --git a/sha256.c b/sha256.c
index d2f915f..279e3cf 100644
--- a/sha256.c
+++ b/sha256.c
@@ -203,15 +203,15 @@ SHA256_Pad(SHA256_CTX * ctx)
    /* Add 1--64 bytes so that the resulting length is 56 mod 64 */
    r = (ctx->count[1] >> 3) & 0x3f;
    plen = (r < 56) ? (56 - r) : (120 - r);
-   SHA256_Update(ctx, PAD, (size_t)plen);
+   libscrypt_SHA256_Update(ctx, PAD, (size_t)plen);

    /* Add the terminating bit-count */
-   SHA256_Update(ctx, len, 8);
+   libscrypt_SHA256_Update(ctx, len, 8);
 }

 /* SHA-256 initialization.  Begins a SHA-256 operation. */
 void
-SHA256_Init(SHA256_CTX * ctx)
+libscrypt_SHA256_Init(SHA256_CTX * ctx)
 {

    /* Zero bits processed so far */
@@ -230,7 +230,7 @@ SHA256_Init(SHA256_CTX * ctx)

 /* Add bytes into the hash */
 void
-SHA256_Update(SHA256_CTX * ctx, const void *in, size_t len)
+libscrypt_SHA256_Update(SHA256_CTX * ctx, const void *in, size_t len)
 {
    uint32_t bitlen[2];
    uint32_t r;
@@ -276,7 +276,7 @@ SHA256_Update(SHA256_CTX * ctx, const void *in, size_t len)
  * and clears the context state.
  */
 void
-SHA256_Final(unsigned char digest[32], SHA256_CTX * ctx)
+libscrypt_SHA256_Final(unsigned char digest[32], SHA256_CTX * ctx)
 {

    /* Add padding */
@@ -291,7 +291,7 @@ SHA256_Final(unsigned char digest[32], SHA256_CTX * ctx)

 /* Initialize an HMAC-SHA256 operation with the given key. */
 void
-HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)
+libscrypt_HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)
 {
    unsigned char pad[64];
    unsigned char khash[32];
@@ -300,26 +300,26 @@ HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)

    /* If Klen > 64, the key is really SHA256(K). */
    if (Klen > 64) {
-       SHA256_Init(&ctx->ictx);
-       SHA256_Update(&ctx->ictx, K, Klen);
-       SHA256_Final(khash, &ctx->ictx);
+       libscrypt_SHA256_Init(&ctx->ictx);
+       libscrypt_SHA256_Update(&ctx->ictx, K, Klen);
+       libscrypt_SHA256_Final(khash, &ctx->ictx);
        K = khash;
        Klen = 32;
    }

    /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */
-   SHA256_Init(&ctx->ictx);
+   libscrypt_SHA256_Init(&ctx->ictx);
    memset(pad, 0x36, 64);
    for (i = 0; i < Klen; i++)
        pad[i] ^= K[i];
-   SHA256_Update(&ctx->ictx, pad, 64);
+   libscrypt_SHA256_Update(&ctx->ictx, pad, 64);

    /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */
-   SHA256_Init(&ctx->octx);
+   libscrypt_SHA256_Init(&ctx->octx);
    memset(pad, 0x5c, 64);
    for (i = 0; i < Klen; i++)
        pad[i] ^= K[i];
-   SHA256_Update(&ctx->octx, pad, 64);
+   libscrypt_SHA256_Update(&ctx->octx, pad, 64);

    /* Clean the stack. */
    memset(khash, 0, 32);
@@ -327,27 +327,27 @@ HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)

 /* Add bytes to the HMAC-SHA256 operation. */
 void
-HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void *in, size_t len)
+libscrypt_HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void *in, size_t len)
 {

    /* Feed data to the inner SHA256 operation. */
-   SHA256_Update(&ctx->ictx, in, len);
+   libscrypt_SHA256_Update(&ctx->ictx, in, len);
 }

 /* Finish an HMAC-SHA256 operation. */
 void
-HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx)
+libscrypt_HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx)
 {
    unsigned char ihash[32];

    /* Finish the inner SHA256 operation. */
-   SHA256_Final(ihash, &ctx->ictx);
+   libscrypt_SHA256_Final(ihash, &ctx->ictx);

    /* Feed the inner hash to the outer SHA256 operation. */
-   SHA256_Update(&ctx->octx, ihash, 32);
+   libscrypt_SHA256_Update(&ctx->octx, ihash, 32);

    /* Finish the outer SHA256 operation. */
-   SHA256_Final(digest, &ctx->octx);
+   libscrypt_SHA256_Final(digest, &ctx->octx);

    /* Clean the stack. */
    memset(ihash, 0, 32);
@@ -359,7 +359,7 @@ HMAC_SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX * ctx)
  * write the output to buf.  The value dkLen must be at most 32 * (2^32 - 1).
  */
 void
-PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
+libscrypt_PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
     size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
 {
    HMAC_SHA256_CTX PShctx, hctx;
@@ -372,8 +372,8 @@ PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
    size_t clen;

    /* Compute HMAC state after processing P and S. */
-   HMAC_SHA256_Init(&PShctx, passwd, passwdlen);
-   HMAC_SHA256_Update(&PShctx, salt, saltlen);
+   libscrypt_HMAC_SHA256_Init(&PShctx, passwd, passwdlen);
+   libscrypt_HMAC_SHA256_Update(&PShctx, salt, saltlen);

    /* Iterate through the blocks. */
    for (i = 0; i * 32 < dkLen; i++) {
@@ -382,17 +382,17 @@ PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,

        /* Compute U_1 = PRF(P, S || INT(i)). */
        memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX));
-       HMAC_SHA256_Update(&hctx, ivec, 4);
-       HMAC_SHA256_Final(U, &hctx);
+       libscrypt_HMAC_SHA256_Update(&hctx, ivec, 4);
+       libscrypt_HMAC_SHA256_Final(U, &hctx);

        /* T_i = U_1 ... */
        memcpy(T, U, 32);

        for (j = 2; j <= c; j++) {
            /* Compute U_j. */
-           HMAC_SHA256_Init(&hctx, passwd, passwdlen);
-           HMAC_SHA256_Update(&hctx, U, 32);
-           HMAC_SHA256_Final(U, &hctx);
+           libscrypt_HMAC_SHA256_Init(&hctx, passwd, passwdlen);
+           libscrypt_HMAC_SHA256_Update(&hctx, U, 32);
+           libscrypt_HMAC_SHA256_Final(U, &hctx);

            /* ... xor U_j ... */
            for (k = 0; k < 32; k++)
diff --git a/sha256.h b/sha256.h
index 580183a..f7138b4 100644
--- a/sha256.h
+++ b/sha256.h
@@ -33,38 +33,38 @@

 #include <stdint.h>

-typedef struct SHA256Context {
+typedef struct libscrypt_SHA256Context {
    uint32_t state[8];
    uint32_t count[2];
    unsigned char buf[64];
 } SHA256_CTX;

-typedef struct HMAC_SHA256Context {
+typedef struct libscrypt_HMAC_SHA256Context {
    SHA256_CTX ictx;
    SHA256_CTX octx;
 } HMAC_SHA256_CTX;

-void   SHA256_Init(/*@out@*/ SHA256_CTX *);
-void   SHA256_Update(SHA256_CTX *, const void *, size_t);
+void   libscrypt_SHA256_Init(/*@out@*/ SHA256_CTX *);
+void   libscrypt_SHA256_Update(SHA256_CTX *, const void *, size_t);

 /* Original declaration: 
  * void    SHA256_Final(unsigned char [32], SHA256_CTX *);
 */
-void   SHA256_Final(/*@out@*/ unsigned char [], SHA256_CTX *);
-void   HMAC_SHA256_Init(HMAC_SHA256_CTX *, const void *, size_t);
-void   HMAC_SHA256_Update(HMAC_SHA256_CTX *, const void *, size_t);
+void   libscrypt_SHA256_Final(/*@out@*/ unsigned char [], SHA256_CTX *);
+void   libscrypt_HMAC_SHA256_Init(HMAC_SHA256_CTX *, const void *, size_t);
+void   libscrypt_HMAC_SHA256_Update(HMAC_SHA256_CTX *, const void *, size_t);

 /* Original declaration:
  * void    HMAC_SHA256_Final(unsigned char [32], HMAC_SHA256_CTX *);
 */
-void   HMAC_SHA256_Final(unsigned char [], HMAC_SHA256_CTX *);
+void   libscrypt_HMAC_SHA256_Final(unsigned char [], HMAC_SHA256_CTX *);

 /**
  * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
  * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
  * write the output to buf.  The value dkLen must be at most 32 * (2^32 - 1).
  */
-void   PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t,
+void   libscrypt_PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t,
     uint64_t, uint8_t *, size_t);

 #endif /* !_SHA256_H_ */

Thank you for this report. I agree this would be a good change to make, however, patches formatted this way don't seem to be easy to apply.
$ git apply kol.patch
error: patch failed: crypto_scrypt-nosse.c:307
error: crypto_scrypt-nosse.c: patch does not apply
error: patch failed: sha256.c:203
error: sha256.c: patch does not apply
error: patch failed: sha256.h:33
error: sha256.h: patch does not apply
(similar issues attempting with the patch command)

Would you be able to:

  • Ensure your start point is the latest git commit
  • Create the patch with git format-patch
  • Upload it as a gist so I can grab a raw copy?
    (alternatively just fork it and make a pull request)

The function names were pulled directly from Colin's reference implementation so I'm surprised this hasn't been a bigger issue for other implementations.

Many thanks for fix in #25