/* Get HMAC Final into digest */ int CRYPT_HMAC_Finalize(CRYPT_HMAC_CTX* hmac, unsigned char* digest) { if (hmac == NULL || digest == NULL) return BAD_FUNC_ARG; return wc_HmacFinal((Hmac*)hmac, digest); }
/* HMAC-KDF-Extract. * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF). * * type The hash algorithm type. * salt The optional salt value. * saltSz The size of the salt. * inKey The input keying material. * inKeySz The size of the input keying material. * out The pseudorandom key with the length that of the hash. * returns 0 on success, otherwise failure. */ int wc_HKDF_Extract(int type, const byte* salt, word32 saltSz, const byte* inKey, word32 inKeySz, byte* out) { byte tmp[MAX_DIGEST_SIZE]; /* localSalt helper */ Hmac myHmac; int ret; const byte* localSalt; /* either points to user input or tmp */ int hashSz; ret = wc_HmacSizeByType(type); if (ret < 0) return ret; hashSz = ret; localSalt = salt; if (localSalt == NULL) { XMEMSET(tmp, 0, hashSz); localSalt = tmp; saltSz = hashSz; } ret = wc_HmacSetKey(&myHmac, type, localSalt, saltSz); if (ret == 0) ret = wc_HmacUpdate(&myHmac, inKey, inKeySz); if (ret == 0) ret = wc_HmacFinal(&myHmac, out); return ret; }
/* HMAC-KDF-Expand. * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF). * * type The hash algorithm type. * inKey The input key. * inKeySz The size of the input key. * info The application specific information. * infoSz The size of the application specific information. * out The output keying material. * returns 0 on success, otherwise failure. */ int wc_HKDF_Expand(int type, const byte* inKey, word32 inKeySz, const byte* info, word32 infoSz, byte* out, word32 outSz) { byte tmp[WC_MAX_DIGEST_SIZE]; Hmac myHmac; int ret = 0; word32 outIdx = 0; word32 hashSz = wc_HmacSizeByType(type); byte n = 0x1; ret = wc_HmacInit(&myHmac, NULL, INVALID_DEVID); if (ret != 0) return ret; while (outIdx < outSz) { int tmpSz = (n == 1) ? 0 : hashSz; word32 left = outSz - outIdx; ret = wc_HmacSetKey(&myHmac, type, inKey, inKeySz); if (ret != 0) break; ret = wc_HmacUpdate(&myHmac, tmp, tmpSz); if (ret != 0) break; ret = wc_HmacUpdate(&myHmac, info, infoSz); if (ret != 0) break; ret = wc_HmacUpdate(&myHmac, &n, 1); if (ret != 0) break; ret = wc_HmacFinal(&myHmac, tmp); if (ret != 0) break; left = min(left, hashSz); XMEMCPY(out+outIdx, tmp, left); outIdx += hashSz; n++; } wc_HmacFree(&myHmac); return ret; }
int wc_PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt, int sLen, int iterations, int kLen, int hashType) { word32 i = 1; int hLen; int j, ret; Hmac hmac; #ifdef WOLFSSL_SMALL_STACK byte* buffer; #else byte buffer[MAX_DIGEST_SIZE]; #endif hLen = GetDigestSize(hashType); if (hLen < 0) return BAD_FUNC_ARG; #ifdef WOLFSSL_SMALL_STACK buffer = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (buffer == NULL) return MEMORY_E; #endif ret = wc_HmacSetKey(&hmac, hashType, passwd, pLen); if (ret == 0) { while (kLen) { int currentLen; ret = wc_HmacUpdate(&hmac, salt, sLen); if (ret != 0) break; /* encode i */ for (j = 0; j < 4; j++) { byte b = (byte)(i >> ((3-j) * 8)); ret = wc_HmacUpdate(&hmac, &b, 1); if (ret != 0) break; } /* check ret from inside for loop */ if (ret != 0) break; ret = wc_HmacFinal(&hmac, buffer); if (ret != 0) break; currentLen = min(kLen, hLen); XMEMCPY(output, buffer, currentLen); for (j = 1; j < iterations; j++) { ret = wc_HmacUpdate(&hmac, buffer, hLen); if (ret != 0) break; ret = wc_HmacFinal(&hmac, buffer); if (ret != 0) break; xorbuf(output, buffer, currentLen); } /* check ret from inside for loop */ if (ret != 0) break; output += currentLen; kLen -= currentLen; i++; } } #ifdef WOLFSSL_SMALL_STACK XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; }
int hmac_sha384_test(void) { Hmac hmac; byte hash[SHA384_DIGEST_SIZE]; const char* keys[]= { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b", "Jefe", "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" "\xAA\xAA\xAA" }; testVector a, b, c; testVector test_hmac[3]; int ret; int times = sizeof(test_hmac) / sizeof(testVector), i; a.input = "Hi There"; a.output = "\xaf\xd0\x39\x44\xd8\x48\x95\x62\x6b\x08\x25\xf4\xab\x46\x90" "\x7f\x15\xf9\xda\xdb\xe4\x10\x1e\xc6\x82\xaa\x03\x4c\x7c\xeb" "\xc5\x9c\xfa\xea\x9e\xa9\x07\x6e\xde\x7f\x4a\xf1\x52\xe8\xb2" "\xfa\x9c\xb6"; a.inLen = XSTRLEN(a.input); a.outLen = XSTRLEN(a.output); b.input = "what do ya want for nothing?"; b.output = "\xaf\x45\xd2\xe3\x76\x48\x40\x31\x61\x7f\x78\xd2\xb5\x8a\x6b" "\x1b\x9c\x7e\xf4\x64\xf5\xa0\x1b\x47\xe4\x2e\xc3\x73\x63\x22" "\x44\x5e\x8e\x22\x40\xca\x5e\x69\xe2\xc7\x8b\x32\x39\xec\xfa" "\xb2\x16\x49"; b.inLen = XSTRLEN(b.input); b.outLen = XSTRLEN(b.output); c.input = "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD"; c.output = "\x88\x06\x26\x08\xd3\xe6\xad\x8a\x0a\xa2\xac\xe0\x14\xc8\xa8" "\x6f\x0a\xa6\x35\xd9\x47\xac\x9f\xeb\xe8\x3e\xf4\xe5\x59\x66" "\x14\x4b\x2a\x5a\xb3\x9d\xc1\x38\x14\xb9\x4e\x3a\xb6\xe1\x01" "\xa3\x4f\x27"; c.inLen = XSTRLEN(c.input); c.outLen = XSTRLEN(c.output); test_hmac[0] = a; test_hmac[1] = b; test_hmac[2] = c; for (i = 0; i < times; ++i) { #if defined(HAVE_FIPS) if (i == 1) continue; /* fips not allowed */ #endif ret = wc_HmacSetKey(&hmac,SHA384, (byte*)keys[i], (word32)XSTRLEN(keys[i])); if (ret != 0) return -4023; ret = wc_HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); if (ret != 0) return -4024; ret = wc_HmacFinal(&hmac, hash); if (ret != 0) return -4025; if (XMEMCMP(hash, test_hmac[i].output, SHA384_DIGEST_SIZE) != 0) return -20 - i; } return 0; }
int hmac_sha256_test(void) { Hmac hmac; byte hash[SHA256_DIGEST_SIZE]; const char* keys[]= { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b", "Jefe", "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" "\xAA\xAA\xAA" }; testVector a, b, c; testVector test_hmac[3]; int ret; int times = sizeof(test_hmac) / sizeof(testVector), i; a.input = "Hi There"; a.output = "\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1" "\x2b\x88\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32" "\xcf\xf7"; a.inLen = XSTRLEN(a.input); a.outLen = XSTRLEN(a.output); b.input = "what do ya want for nothing?"; b.output = "\x5b\xdc\xc1\x46\xbf\x60\x75\x4e\x6a\x04\x24\x26\x08\x95\x75" "\xc7\x5a\x00\x3f\x08\x9d\x27\x39\x83\x9d\xec\x58\xb9\x64\xec" "\x38\x43"; b.inLen = XSTRLEN(b.input); b.outLen = XSTRLEN(b.output); c.input = "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD"; c.output = "\x77\x3e\xa9\x1e\x36\x80\x0e\x46\x85\x4d\xb8\xeb\xd0\x91\x81" "\xa7\x29\x59\x09\x8b\x3e\xf8\xc1\x22\xd9\x63\x55\x14\xce\xd5" "\x65\xfe"; c.inLen = XSTRLEN(c.input); c.outLen = XSTRLEN(c.output); test_hmac[0] = a; test_hmac[1] = b; test_hmac[2] = c; for (i = 0; i < times; ++i) { #if defined(HAVE_FIPS) if (i == 1) continue; /* fips not allowed */ #endif ret = wc_HmacSetKey(&hmac,SHA256, (byte*)keys[i], (word32)XSTRLEN(keys[i])); if (ret != 0) return -4020; ret = wc_HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); if (ret != 0) return -4021; ret = wc_HmacFinal(&hmac, hash); if (ret != 0) return -4022; if (XMEMCMP(hash, test_hmac[i].output, SHA256_DIGEST_SIZE) != 0) return -20 - i; } return 0; }
int hmac_sha224_test(void) { Hmac hmac; byte hash[SHA224_DIGEST_SIZE]; const char* keys[]= { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b", "Jefe", "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" "\xAA\xAA\xAA" }; testVector a, b, c; testVector test_hmac[3]; int ret; int times = sizeof(test_hmac) / sizeof(testVector), i; a.input = "Hi There"; a.output = "\x89\x6f\xb1\x12\x8a\xbb\xdf\x19\x68\x32\x10\x7c\xd4\x9d\xf3" "\x3f\x47\xb4\xb1\x16\x99\x12\xba\x4f\x53\x68\x4b\x22"; a.inLen = XSTRLEN(a.input); a.outLen = SHA224_DIGEST_SIZE; b.input = "what do ya want for nothing?"; b.output = "\xa3\x0e\x01\x09\x8b\xc6\xdb\xbf\x45\x69\x0f\x3a\x7e\x9e\x6d" "\x0f\x8b\xbe\xa2\xa3\x9e\x61\x48\x00\x8f\xd0\x5e\x44"; b.inLen = XSTRLEN(b.input); b.outLen = SHA224_DIGEST_SIZE; c.input = "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD"; c.output = "\x7f\xb3\xcb\x35\x88\xc6\xc1\xf6\xff\xa9\x69\x4d\x7d\x6a\xd2" "\x64\x93\x65\xb0\xc1\xf6\x5d\x69\xd1\xec\x83\x33\xea"; c.inLen = XSTRLEN(c.input); c.outLen = SHA224_DIGEST_SIZE; test_hmac[0] = a; test_hmac[1] = b; test_hmac[2] = c; for (i = 0; i < times; ++i) { #if defined(HAVE_FIPS) || defined(HAVE_CAVIUM) if (i == 1) continue; /* cavium can't handle short keys, fips not allowed */ #endif ret = wc_HmacSetKey(&hmac, SHA224, (byte*)keys[i],(word32)XSTRLEN(keys[i])); if (ret != 0) return -4021; ret = wc_HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); if (ret != 0) return -4022; ret = wc_HmacFinal(&hmac, hash); if (ret != 0) return -4023; if (XMEMCMP(hash, test_hmac[i].output, SHA224_DIGEST_SIZE) != 0) return -20 - i; #ifdef WOLFSSL_ASYNC_CRYPT wc_HmacAsyncFree(&hmac); #endif } return 0; }
int hmac_sha_test(void) { Hmac hmac; byte hash[SHA_DIGEST_SIZE]; const char* keys[]= { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b", "Jefe", "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" "\xAA\xAA\xAA" }; testVector a, b, c; testVector test_hmac[3]; int ret; int times = sizeof(test_hmac) / sizeof(testVector), i; a.input = "Hi There"; a.output = "\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c" "\x8e\xf1\x46\xbe\x00"; a.inLen = XSTRLEN(a.input); a.outLen = XSTRLEN(a.output); b.input = "what do ya want for nothing?"; b.output = "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf" "\x9c\x25\x9a\x7c\x79"; b.inLen = XSTRLEN(b.input); b.outLen = XSTRLEN(b.output); c.input = "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD"; c.output = "\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b" "\x4f\x63\xf1\x75\xd3"; c.inLen = XSTRLEN(c.input); c.outLen = XSTRLEN(c.output); test_hmac[0] = a; test_hmac[1] = b; test_hmac[2] = c; for (i = 0; i < times; ++i) { #if defined(HAVE_FIPS) if (i == 1) continue; /* fips not allowed */ #endif ret = wc_HmacSetKey(&hmac, SHA, (byte*)keys[i], (word32)XSTRLEN(keys[i])); if (ret != 0) return -4017; ret = wc_HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); if (ret != 0) return -4018; ret = wc_HmacFinal(&hmac, hash); if (ret != 0) return -4019; if (XMEMCMP(hash, test_hmac[i].output, SHA_DIGEST_SIZE) != 0) return -20 - i; } return 0; }
int hmac_md5_test(void) { Hmac hmac; byte hash[MD5_DIGEST_SIZE]; const char* keys[]= { "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", "Jefe", "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" }; testVector a, b, c; testVector test_hmac[3]; int ret; int times = sizeof(test_hmac) / sizeof(testVector), i; a.input = "Hi There"; a.output = "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc" "\x9d"; a.inLen = XSTRLEN(a.input); a.outLen = XSTRLEN(a.output); b.input = "what do ya want for nothing?"; b.output = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7" "\x38"; b.inLen = XSTRLEN(b.input); b.outLen = XSTRLEN(b.output); c.input = "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" "\xDD\xDD\xDD\xDD\xDD\xDD"; c.output = "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3" "\xf6"; c.inLen = XSTRLEN(c.input); c.outLen = XSTRLEN(c.output); test_hmac[0] = a; test_hmac[1] = b; test_hmac[2] = c; for (i = 0; i < times; ++i) { #if defined(HAVE_FIPS) if (i == 1) continue; /* fips not allowed */ #endif ret = wc_HmacSetKey(&hmac, MD5, (byte*)keys[i], (word32)XSTRLEN(keys[i])); if (ret != 0) return -4014; ret = wc_HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); if (ret != 0) return -4015; ret = wc_HmacFinal(&hmac, hash); if (ret != 0) return -4016; if (XMEMCMP(hash, test_hmac[i].output, MD5_DIGEST_SIZE) != 0) return -20 - i; } return 0; }
/* HMAC-KDF with hash type, optional salt and info, return 0 on success */ int wc_HKDF(int type, const byte* inKey, word32 inKeySz, const byte* salt, word32 saltSz, const byte* info, word32 infoSz, byte* out, word32 outSz) { Hmac myHmac; #ifdef WOLFSSL_SMALL_STACK byte* tmp; byte* prk; #else byte tmp[MAX_DIGEST_SIZE]; /* localSalt helper and T */ byte prk[MAX_DIGEST_SIZE]; #endif const byte* localSalt; /* either points to user input or tmp */ int hashSz = GetHashSizeByType(type); word32 outIdx = 0; byte n = 0x1; int ret; if (hashSz < 0) return BAD_FUNC_ARG; #ifdef WOLFSSL_SMALL_STACK tmp = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) return MEMORY_E; prk = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (prk == NULL) { XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E; } #endif localSalt = salt; if (localSalt == NULL) { XMEMSET(tmp, 0, hashSz); localSalt = tmp; saltSz = hashSz; } do { ret = wc_HmacSetKey(&myHmac, type, localSalt, saltSz); if (ret != 0) break; ret = wc_HmacUpdate(&myHmac, inKey, inKeySz); if (ret != 0) break; ret = wc_HmacFinal(&myHmac, prk); } while (0); if (ret == 0) { while (outIdx < outSz) { int tmpSz = (n == 1) ? 0 : hashSz; word32 left = outSz - outIdx; ret = wc_HmacSetKey(&myHmac, type, prk, hashSz); if (ret != 0) break; ret = wc_HmacUpdate(&myHmac, tmp, tmpSz); if (ret != 0) break; ret = wc_HmacUpdate(&myHmac, info, infoSz); if (ret != 0) break; ret = wc_HmacUpdate(&myHmac, &n, 1); if (ret != 0) break; ret = wc_HmacFinal(&myHmac, tmp); if (ret != 0) break; left = min(left, (word32)hashSz); XMEMCPY(out+outIdx, tmp, left); outIdx += hashSz; n++; } } #ifdef WOLFSSL_SMALL_STACK XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(prk, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; }
/* check mac on pkcs12, pkcs12->mac has been sanity checked before entering * * returns the result of comparison, success is 0 */ static int wc_PKCS12_verify(WC_PKCS12* pkcs12, byte* data, word32 dataSz, const byte* psw, word32 pswSz) { Hmac hmac; MacData* mac; int ret, typeH, kLen; int idx = 0; int id = 3; /* value from RFC 7292 indicating key is used for MAC */ word32 i; byte digest[MAX_DIGEST_SIZE]; byte unicodePasswd[MAX_UNICODE_SZ]; byte key[MAX_KEY_SIZE]; mac = pkcs12->signData; #ifdef WOLFSSL_DEBUG_PKCS12 printf("Verifying MAC with OID = %d\n", mac->oid); #endif /* check if this builds digest size is too small */ if (mac->digestSz > MAX_DIGEST_SIZE) { WOLFSSL_MSG("PKCS12 max digest size too small"); return BAD_FUNC_ARG; } /* unicode set up from asn.c */ if ( (pswSz * 2 + 2) > (int)sizeof(unicodePasswd)) { WOLFSSL_MSG("PKCS12 max unicode size too small"); return UNICODE_SIZE_E; } for (i = 0; i < pswSz; i++) { unicodePasswd[idx++] = 0x00; unicodePasswd[idx++] = (byte)psw[i]; } /* add trailing NULL */ unicodePasswd[idx++] = 0x00; unicodePasswd[idx++] = 0x00; /* get hash type used and resulting size of HMAC key */ switch (mac->oid) { #ifndef NO_SHA case SHAh: /* 88 */ typeH = SHA; kLen = SHA_DIGEST_SIZE; break; #endif #ifndef NO_SHA256 case SHA256h: /* 414 */ typeH = SHA256; kLen = SHA256_DIGEST_SIZE; break; #endif #ifdef WOLFSSL_SHA384 case SHA384h: /* 415 */ typeH = SHA384; kLen = SHA384_DIGEST_SIZE; break; #endif #ifdef WOLFSSL_SHA512 case SHA512h: /* 416 */ typeH = SHA512; kLen = SHA512_DIGEST_SIZE; break; #endif default: /* May be SHA224 or was just not built in */ WOLFSSL_MSG("Unsupported hash used"); return BAD_FUNC_ARG; } /* idx contains size of unicodePasswd */ if ((ret = wc_PKCS12_PBKDF_ex(key, unicodePasswd, idx, mac->salt, mac->saltSz, mac->itt, kLen, typeH, id, pkcs12->heap)) < 0) { return ret; } /* now that key has been created use it to get HMAC hash on data */ if ((ret = wc_HmacSetKey(&hmac, typeH, key, kLen)) != 0) { return ret; } if ((ret = wc_HmacUpdate(&hmac, data, dataSz)) != 0) { return ret; } if ((ret = wc_HmacFinal(&hmac, digest)) != 0) { return ret; } #ifdef WOLFSSL_DEBUG_PKCS12 { byte* p; for (printf("\t\tHash = "), p = (byte*)digest; p < (byte*)digest + mac->digestSz; printf("%02X", *p), p++); printf(" : size = %d\n", mac->digestSz); } #endif return XMEMCMP(digest, mac->digest, mac->digestSz); }
/* check mcapi hmac against internal */ static int check_hmac(void) { CRYPT_HMAC_CTX mcHmac; Hmac defHmac; int ret; byte mcDigest[CRYPT_SHA512_DIGEST_SIZE]; byte defDigest[SHA512_DIGEST_SIZE]; strncpy((char*)key, "Jefe", 4); /* SHA1 */ CRYPT_HMAC_SetKey(&mcHmac, CRYPT_HMAC_SHA, key, 4); ret = wc_HmacSetKey(&defHmac, SHA, key, 4); if (ret != 0) { printf("hmac sha setkey default failed\n"); return -1; } CRYPT_HMAC_DataAdd(&mcHmac, ourData, OUR_DATA_SIZE); ret = wc_HmacUpdate(&defHmac, ourData, OUR_DATA_SIZE); if (ret != 0) { printf("hmac sha update default failed\n"); return -1; } CRYPT_HMAC_Finalize(&mcHmac, mcDigest); ret = wc_HmacFinal(&defHmac, defDigest); if (ret != 0) { printf("hmac sha final default failed\n"); return -1; } if (memcmp(mcDigest, defDigest, CRYPT_SHA_DIGEST_SIZE) != 0) { printf("hmac sha final memcmp fialed\n"); return -1; } printf("hmac sha mcapi test passed\n"); /* SHA-256 */ CRYPT_HMAC_SetKey(&mcHmac, CRYPT_HMAC_SHA256, key, 4); ret = wc_HmacSetKey(&defHmac, SHA256, key, 4); if (ret != 0) { printf("hmac sha256 setkey default failed\n"); return -1; } CRYPT_HMAC_DataAdd(&mcHmac, ourData, OUR_DATA_SIZE); ret = wc_HmacUpdate(&defHmac, ourData, OUR_DATA_SIZE); if (ret != 0) { printf("hmac sha256 update default failed\n"); return -1; } CRYPT_HMAC_Finalize(&mcHmac, mcDigest); ret = wc_HmacFinal(&defHmac, defDigest); if (ret != 0) { printf("hmac sha256 final default failed\n"); return -1; } if (memcmp(mcDigest, defDigest, CRYPT_SHA256_DIGEST_SIZE) != 0) { printf("hmac sha256 final memcmp fialed\n"); return -1; } printf("hmac sha256 mcapi test passed\n"); /* SHA-384 */ CRYPT_HMAC_SetKey(&mcHmac, CRYPT_HMAC_SHA384, key, 4); ret = wc_HmacSetKey(&defHmac, SHA384, key, 4); if (ret != 0) { printf("hmac sha384 setkey default failed\n"); return -1; } CRYPT_HMAC_DataAdd(&mcHmac, ourData, OUR_DATA_SIZE); ret = wc_HmacUpdate(&defHmac, ourData, OUR_DATA_SIZE); if (ret != 0) { printf("hmac sha384 update default failed\n"); return -1; } CRYPT_HMAC_Finalize(&mcHmac, mcDigest); ret = wc_HmacFinal(&defHmac, defDigest); if (ret != 0) { printf("hmac sha384 final default failed\n"); return -1; } if (memcmp(mcDigest, defDigest, CRYPT_SHA384_DIGEST_SIZE) != 0) { printf("hmac sha384 final memcmp fialed\n"); return -1; } printf("hmac sha384 mcapi test passed\n"); /* SHA-512 */ CRYPT_HMAC_SetKey(&mcHmac, CRYPT_HMAC_SHA512, key, 4); ret = wc_HmacSetKey(&defHmac, SHA512, key, 4); if (ret != 0) { printf("hmac sha512 setkey default failed\n"); return -1; } CRYPT_HMAC_DataAdd(&mcHmac, ourData, OUR_DATA_SIZE); ret = wc_HmacUpdate(&defHmac, ourData, OUR_DATA_SIZE); if (ret != 0) { printf("hmac sha512 update default failed\n"); return -1; } CRYPT_HMAC_Finalize(&mcHmac, mcDigest); ret = wc_HmacFinal(&defHmac, defDigest); if (ret != 0) { printf("hmac sha512 final default failed\n"); return -1; } if (memcmp(mcDigest, defDigest, CRYPT_SHA512_DIGEST_SIZE) != 0) { printf("hmac sha512 final memcmp fialed\n"); return -1; } printf("hmac sha512 mcapi test passed\n"); return 0; }