int32_t psHmacSha256Init(psHmacSha256_t *ctx, const unsigned char *key, uint16_t keyLen) { int32_t rc, i, padLen = 64; #ifdef CRYPTO_ASSERT psAssert(keyLen <= (uint32)padLen); #endif for (i = 0; (uint32)i < keyLen; i++) { ctx->pad[i] = key[i] ^ 0x36; } for (i = keyLen; i < padLen; i++) { ctx->pad[i] = 0x36; } if ((rc = psSha256Init(&ctx->sha256)) < 0) { return rc; } psSha256Update(&ctx->sha256, ctx->pad, padLen); for (i = 0; (uint32)i < keyLen; i++) { ctx->pad[i] = key[i] ^ 0x5c; } for (i = keyLen; i < padLen; i++) { ctx->pad[i] = 0x5c; } return PS_SUCCESS; }
int32 psHmacSha2Final(psHmacContext_t *ctx, unsigned char *hash, uint32 hashSize) { psAssert(ctx != NULL); if (hash == NULL) { psTraceCrypto("NULL hash storage passed to psHmacSha256Final\n"); return PS_ARG_FAIL; } if (hashSize == SHA384_HASH_SIZE) { #ifdef USE_SHA384 psSha384Final(&ctx->u.sha512, hash); psSha384Init(&ctx->u.sha512); psSha384Update(&ctx->u.sha512, ctx->pad, 128); psSha384Update(&ctx->u.sha512, hash, SHA384_HASH_SIZE); psSha384Final(&ctx->u.sha512, hash); #else return PS_UNSUPPORTED_FAIL; #endif } else { psSha256Final(&ctx->u.sha256, hash); psSha256Init(&ctx->u.sha256); psSha256Update(&ctx->u.sha256, ctx->pad, 64); psSha256Update(&ctx->u.sha256, hash, SHA256_HASH_SIZE); psSha256Final(&ctx->u.sha256, hash); } memset(ctx->pad, 0x0, sizeof(ctx->pad)); return hashSize; }
void psHmacSha2Init(psHmacContext_t *ctx, unsigned char *key, uint32 keyLen, uint32 hashSize) { int32 i, padLen = 64; #ifdef USE_SHA384 if (hashSize == SHA384_HASH_SIZE) { padLen = 128; } #endif psAssert(keyLen <= (uint32)padLen); for (i = 0; (uint32)i < keyLen; i++) { ctx->pad[i] = key[i] ^ 0x36; } for (i = keyLen; i < padLen; i++) { ctx->pad[i] = 0x36; } if (hashSize == SHA384_HASH_SIZE) { #ifdef USE_SHA384 psSha384Init(&ctx->u.sha512); psSha384Update(&ctx->u.sha512, ctx->pad, padLen); #endif } else { psSha256Init(&ctx->u.sha256); psSha256Update(&ctx->u.sha256, ctx->pad, padLen); } for (i = 0; (uint32)i < keyLen; i++) { ctx->pad[i] = key[i] ^ 0x5c; } for (i = keyLen; i < padLen; i++) { ctx->pad[i] = 0x5c; } }
int32 psSha256Test(void) { psDigestContext_t ctx; psSha256Init(&ctx.sha256); runDigestTime(&ctx, TINY_CHUNKS, SHA256_ALG); runDigestTime(&ctx, SMALL_CHUNKS, SHA256_ALG); runDigestTime(&ctx, MEDIUM_CHUNKS, SHA256_ALG); runDigestTime(&ctx, LARGE_CHUNKS, SHA256_ALG); runDigestTime(&ctx, HUGE_CHUNKS, SHA256_ALG); return PS_SUCCESS; }
/* Initialize the SHA1 and MD5 hash contexts for the handshake messages */ int32 sslInitHSHash(ssl_t *ssl) { #ifndef USE_ONLY_TLS_1_2 psSha1Init(&ssl->sec.msgHashSha1); psMd5Init(&ssl->sec.msgHashMd5); #endif #ifdef USE_TLS_1_2 psSha256Init(&ssl->sec.msgHashSha256); #ifdef USE_SHA384 psSha384Init(&ssl->sec.msgHashSha384); #endif #endif return 0; }
int32 psHmacSha2(unsigned char *key, uint32 keyLen, const unsigned char *buf, uint32 len, unsigned char *hash, unsigned char *hmacKey, uint32 *hmacKeyLen, uint32 hashSize) { psHmacContext_t ctx; psDigestContext_t sha; int32 padLen = 64; #ifdef USE_SHA384 if (hashSize == SHA384_HASH_SIZE) { padLen = 128; } #endif /* Support for keys larger than hash block size. In this case, we take the hash of the key itself and use that instead. Inform the caller by updating the hmacKey and hmacKeyLen outputs */ if (keyLen > (uint32)padLen) { if (hashSize == SHA384_HASH_SIZE) { #ifdef USE_SHA384 psSha384Init(&sha); psSha384Update(&sha, key, keyLen); psSha384Final(&sha, hash); #else return PS_UNSUPPORTED_FAIL; #endif } else { psSha256Init(&sha); psSha256Update(&sha, key, keyLen); psSha256Final(&sha, hash); } *hmacKeyLen = hashSize; memcpy(hmacKey, hash, *hmacKeyLen); } else { hmacKey = key; *hmacKeyLen = keyLen; } psHmacSha2Init(&ctx, hmacKey, *hmacKeyLen, hashSize); psHmacSha2Update(&ctx, buf, len, hashSize); return psHmacSha2Final(&ctx, hash, hashSize); }
/* HMAC-SHA256 */ int32_t psHmacSha256(const unsigned char *key, uint16_t keyLen, const unsigned char *buf, uint32_t len, unsigned char hash[SHA256_HASHLEN], unsigned char *hmacKey, uint16_t *hmacKeyLen) { int32 rc, padLen; union { psHmacSha256_t mac; psSha256_t md; } u; psHmacSha256_t *mac = &u.mac; psSha256_t *md = &u.md; padLen = 64; /* Support for keys larger than hash block size. In this case, we take the hash of the key itself and use that instead. Inform the caller by updating the hmacKey and hmacKeyLen outputs */ if (keyLen > (uint32)padLen) { if ((rc = psSha256Init(md)) < 0) { return rc; } psSha256Update(md, key, keyLen); psSha256Final(md, hash); memcpy(hmacKey, hash, SHA256_HASHLEN); *hmacKeyLen = SHA256_HASHLEN; } else { hmacKey = (unsigned char *)key; /* @note typecasting from const */ *hmacKeyLen = keyLen; } if ((rc = psHmacSha256Init(mac, hmacKey, *hmacKeyLen)) < 0) { return rc; } psHmacSha256Update(mac, buf, len); psHmacSha256Final(mac, hash); return PS_SUCCESS; }
/** Add entropy to the PRNG state @param in The data to add @param inlen Length of the data to add @param prng PRNG state to update */ int32 psYarrowAddEntropy(unsigned char *in, uint32 inlen, psYarrow_t *prng) { psDigestContext_t md; int32 err; if (in == NULL || prng == NULL) { return PS_ARG_FAIL; } #ifdef USE_SHA256 /* start the hash */ psSha256Init(&md); /* hash the current pool */ psSha256Update(&md, prng->pool, SHA256_HASH_SIZE); /* add the new entropy */ psSha256Update(&md, in, inlen); /* store result */ if ((err = psSha256Final(&md, prng->pool)) != SHA256_HASH_SIZE) { return err; } #else /* start the hash */ psSha1Init(&md); /* hash the current pool */ psSha1Update(&md, prng->pool, SHA1_HASH_SIZE); /* add the new entropy */ psSha1Update(&md, in, inlen); /* store result */ if ((err = psSha1Final(&md, prng->pool)) != SHA1_HASH_SIZE) { return err; } #endif return PS_SUCCESS; }
int32_t psHmacSha256(const unsigned char *key, uint16_t keyLen, const unsigned char *buf, uint32_t len, unsigned char hash[SHA256_HASHLEN], unsigned char *hmacKey, uint16_t *hmacKeyLen) { psSha256_t sha; if (keyLen > 64) { psSha256Init(&sha); psSha256Update(&sha, key, keyLen); psSha256Final(&sha, hash); *hmacKeyLen = SHA256_HASHLEN; memcpy(hmacKey, hash, *hmacKeyLen); } else { hmacKey = (unsigned char*)key; *hmacKeyLen = keyLen; } if (HMAC(EVP_sha256(), hmacKey, *hmacKeyLen, buf, len, hash, NULL) != NULL) { return PS_SUCCESS; } psAssert(0); return PS_FAIL; }
void psHmacSha256Final(psHmacSha256_t *ctx, unsigned char hash[SHA256_HASHLEN]) { int32_t rc; #ifdef CRYPTO_ASSERT psAssert(ctx != NULL); if (hash == NULL) { psTraceCrypto("NULL hash storage passed to psHmacSha256Final\n"); return; } #endif psSha256Final(&ctx->sha256, hash); if ((rc = psSha256Init(&ctx->sha256)) < 0) { psAssert(rc >= 0); return; } psSha256Update(&ctx->sha256, ctx->pad, 64); psSha256Update(&ctx->sha256, hash, SHA256_HASHLEN); psSha256Final(&ctx->sha256, hash); memset(ctx->pad, 0x0, sizeof(ctx->pad)); }