/* SHA1 portion of the prf */ __inline static int32_t pSha1(const unsigned char *key, uint16_t keyLen, const unsigned char *text, uint16_t textLen, unsigned char *out, uint16_t outLen) { psHmacSha1_t ctx; unsigned char a[SHA1_HASH_SIZE]; unsigned char mac[SHA1_HASH_SIZE]; unsigned char hmacKey[SHA1_HASH_SIZE]; int32_t rc = PS_FAIL; uint16_t hmacKeyLen, i, keyIter; for (keyIter = 1; (uint16_t)(SHA1_HASH_SIZE * keyIter) < outLen;) { keyIter++; } if ((rc = psHmacSha1(key, keyLen, text, textLen, a, hmacKey, &hmacKeyLen)) < 0) { goto L_RETURN; } if (hmacKeyLen != keyLen) { /* Support for keys larger than 64 bytes. Must take the hash of the original key in these cases which is indicated by different outgoing values from the passed in key and keyLen values */ psAssert(keyLen > 64); /* Typecast is OK, we don't update key below */ key = (const unsigned char *)hmacKey; keyLen = hmacKeyLen; } for (i = 0; i < keyIter; i++) { if ((rc = psHmacSha1Init(&ctx, key, keyLen)) < 0) { goto L_RETURN; } psHmacSha1Update(&ctx, a, SHA1_HASH_SIZE); psHmacSha1Update(&ctx, text, textLen); psHmacSha1Final(&ctx, mac); if (i == keyIter - 1) { memcpy(out + (SHA1_HASH_SIZE * i), mac, outLen - (SHA1_HASH_SIZE * i)); } else { memcpy(out + (SHA1_HASH_SIZE * i), mac, SHA1_HASH_SIZE); if ((rc = psHmacSha1(key, keyLen, a, SHA1_HASH_SIZE, a, hmacKey, &hmacKeyLen)) < 0) { goto L_RETURN; } } } rc = PS_SUCCESS; L_RETURN: memzero_s(a, SHA1_HASH_SIZE); memzero_s(mac, SHA1_HASH_SIZE); memzero_s(hmacKey, SHA1_HASH_SIZE); if (rc < 0) { memzero_s(out, outLen); /* zero any partial result on error */ } return rc; }
/* SHA1 portion of the prf */ static int32 pSha1(unsigned char *key, uint32 keyLen, unsigned char *text, uint32 textLen, unsigned char *out, uint32 outLen) { psHmacContext_t ctx; unsigned char a[SHA1_HASH_SIZE]; unsigned char mac[SHA1_HASH_SIZE]; unsigned char hmacKey[SHA1_HASH_SIZE]; int32 i, keyIter = 1; uint32 hmacKeyLen; while ((uint32)(SHA1_HASH_SIZE * keyIter) < outLen) { keyIter++; } psHmacSha1(key, keyLen, text, textLen, a, hmacKey, &hmacKeyLen); if (hmacKeyLen != keyLen) { /* Support for keys larger than 64 bytes. Must take the hash of the original key in these cases which is indicated by different outgoing values from the passed in key and keyLen values */ psAssert(keyLen > 64); key = hmacKey; keyLen = hmacKeyLen; } for (i = 0; i < keyIter; i++) { psHmacSha1Init(&ctx, key, keyLen); psHmacSha1Update(&ctx, a, SHA1_HASH_SIZE); psHmacSha1Update(&ctx, text, textLen); psHmacSha1Final(&ctx, mac); if (i == keyIter - 1) { memcpy(out + (SHA1_HASH_SIZE * i), mac, outLen - (SHA1_HASH_SIZE * i)); } else { memcpy(out + (SHA1_HASH_SIZE * i), mac, SHA1_HASH_SIZE); psHmacSha1(key, keyLen, a, SHA1_HASH_SIZE, a, hmacKey, &hmacKeyLen); } } return 0; }