void HmacFinal(Hmac* hmac, byte* hash) { if (!hmac->innerHashKeyed) HmacKeyInnerHash(hmac); if (hmac->macType == MD5) { Md5Final(&hmac->hash.md5, (byte*) hmac->innerHash); Md5Update(&hmac->hash.md5, (byte*) hmac->opad, HMAC_BLOCK_SIZE); Md5Update(&hmac->hash.md5, (byte*) hmac->innerHash, MD5_DIGEST_SIZE); Md5Final(&hmac->hash.md5, hash); } else if (hmac->macType ==SHA) { ShaFinal(&hmac->hash.sha, (byte*) hmac->innerHash); ShaUpdate(&hmac->hash.sha, (byte*) hmac->opad, HMAC_BLOCK_SIZE); ShaUpdate(&hmac->hash.sha, (byte*) hmac->innerHash, SHA_DIGEST_SIZE); ShaFinal(&hmac->hash.sha, hash); } #ifndef NO_SHA256 else if (hmac->macType ==SHA256) { Sha256Final(&hmac->hash.sha256, (byte*) hmac->innerHash); Sha256Update(&hmac->hash.sha256, (byte*) hmac->opad, HMAC_BLOCK_SIZE); Sha256Update(&hmac->hash.sha256, (byte*) hmac->innerHash, SHA256_DIGEST_SIZE); Sha256Final(&hmac->hash.sha256, hash); } #endif hmac->innerHashKeyed = 0; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // TestMd5 // // Test MD5 algorithm against test vectors /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static bool TestMd5 ( void ) { int i; int k; int len; Md5Context context; MD5_HASH hash; bool success = true; for( i=0; i<NUM_TEST_VECTORS; i++ ) { Md5Initialise( &context ); len = (int) gTestVectors[i].PlainTextSize ? gTestVectors[i].PlainTextSize : (int)strlen( gTestVectors[i].PlainText ); Md5Update( &context, gTestVectors[i].PlainText, (uint32_t)len ); Md5Finalise( &context, &hash ); if( memcmp( &hash, &gTestVectors[i].Md5Hash, sizeof(hash) ) == 0 ) { // Test vector passed } else { printf( "TestMd5 - Test vector %u failed\n", i ); success = false; } } // Check the vectors again, this time adding just 1 char at a time to the hash functions for( i=0; i<NUM_TEST_VECTORS; i++ ) { Md5Initialise( &context ); len = (int) gTestVectors[i].PlainTextSize ? gTestVectors[i].PlainTextSize : (int)strlen( gTestVectors[i].PlainText ); for( k=0; k<len; k++ ) { Md5Update( &context, &gTestVectors[i].PlainText[k], 1 ); } Md5Finalise( &context, &hash ); if( memcmp( &hash, &gTestVectors[i].Md5Hash, sizeof(hash) ) == 0 ) { // Test vector passed } else { printf( "TestMd5 - Test vector %u failed [byte by byte]\n", i ); success = false; } } return success; }
void bench_md5(void) { Md5 hash; byte digest[MD5_DIGEST_SIZE]; double start, total, persec; int i; InitMd5(&hash); start = current_time(1); for(i = 0; i < numBlocks; i++) Md5Update(&hash, plain, sizeof(plain)); Md5Final(&hash, digest); total = current_time(0) - start; persec = 1 / total * numBlocks; #ifdef BENCH_EMBEDDED /* since using kB, convert to MB/s */ persec = persec / 1024; #endif printf("MD5 %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks, blockType, total, persec); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // main // // Program entry point //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int main ( int ArgC, char** ArgV ) { char* string; Md5Context md5Context; MD5_HASH md5Hash; uint16_t i; if( 2 != ArgC ) { printf( "Syntax\n" " Md5String <String>\n" ); return 1; } string = ArgV[1]; Md5Initialise( &md5Context ); Md5Update( &md5Context, string, (uint32_t)strlen(string) ); Md5Finalise( &md5Context, &md5Hash ); for( i=0; i<sizeof(md5Hash); i++ ) { printf( "0x%2.2x,", md5Hash.bytes[i] ); } printf( "\n" ); return 0; }
void file_test(char* file, byte* check) { FILE* f; int i = 0, j; Md5 md5; byte buf[1024]; byte md5sum[MD5_DIGEST_SIZE]; InitMd5(&md5); if( !( f = fopen( file, "rb" ) )) { printf("Can't open %s\n", file); return; } while( ( i = (int)fread(buf, 1, sizeof(buf), f )) > 0 ) Md5Update(&md5, buf, i); Md5Final(&md5, md5sum); memcpy(check, md5sum, sizeof(md5sum)); for(j = 0; j < MD5_DIGEST_SIZE; ++j ) printf( "%02x", md5sum[j] ); printf(" %s\n", file); fclose(f); }
int PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt, int sLen, int iterations, int kLen, int hashType) { Md5 md5; Sha sha; int hLen = (hashType == MD5) ? (int)MD5_DIGEST_SIZE : (int)SHA_DIGEST_SIZE; int i, ret = 0; byte buffer[SHA_DIGEST_SIZE]; /* max size */ if (hashType != MD5 && hashType != SHA) return BAD_FUNC_ARG; if (kLen > hLen) return BAD_FUNC_ARG; if (iterations < 1) return BAD_FUNC_ARG; if (hashType == MD5) { InitMd5(&md5); Md5Update(&md5, passwd, pLen); Md5Update(&md5, salt, sLen); Md5Final(&md5, buffer); } else { ret = InitSha(&sha); if (ret != 0) return ret; ShaUpdate(&sha, passwd, pLen); ShaUpdate(&sha, salt, sLen); ShaFinal(&sha, buffer); } for (i = 1; i < iterations; i++) { if (hashType == MD5) { Md5Update(&md5, buffer, hLen); Md5Final(&md5, buffer); } else { ShaUpdate(&sha, buffer, hLen); ShaFinal(&sha, buffer); } } XMEMCPY(output, buffer, kLen); return 0; }
int md5_test() { Md5 md5; byte hash[MD5_DIGEST_SIZE]; testVector a, b, c, d, e; testVector test_md5[5]; int times = sizeof(test_md5) / sizeof(testVector), i; a.input = "abc"; a.output = "\x90\x01\x50\x98\x3c\xd2\x4f\xb0\xd6\x96\x3f\x7d\x28\xe1\x7f" "\x72"; a.inLen = strlen(a.input); a.outLen = strlen(a.output); b.input = "message digest"; b.output = "\xf9\x6b\x69\x7d\x7c\xb7\x93\x8d\x52\x5a\x2f\x31\xaa\xf1\x61" "\xd0"; b.inLen = strlen(b.input); b.outLen = strlen(b.output); c.input = "abcdefghijklmnopqrstuvwxyz"; c.output = "\xc3\xfc\xd3\xd7\x61\x92\xe4\x00\x7d\xfb\x49\x6c\xca\x67\xe1" "\x3b"; c.inLen = strlen(c.input); c.outLen = strlen(c.output); d.input = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345" "6789"; d.output = "\xd1\x74\xab\x98\xd2\x77\xd9\xf5\xa5\x61\x1c\x2c\x9f\x41\x9d" "\x9f"; d.inLen = strlen(d.input); d.outLen = strlen(d.output); e.input = "1234567890123456789012345678901234567890123456789012345678" "9012345678901234567890"; e.output = "\x57\xed\xf4\xa2\x2b\xe3\xc9\x55\xac\x49\xda\x2e\x21\x07\xb6" "\x7a"; e.inLen = strlen(e.input); e.outLen = strlen(e.output); test_md5[0] = a; test_md5[1] = b; test_md5[2] = c; test_md5[3] = d; test_md5[4] = e; InitMd5(&md5); for (i = 0; i < times; ++i) { Md5Update(&md5, (byte*)test_md5[i].input, (word32)test_md5[i].inLen); Md5Final(&md5, hash); if (memcmp(hash, test_md5[i].output, MD5_DIGEST_SIZE) != 0) return -5 - i; } return 0; }
void sg_md5_update(sg_md5_ctx *mc, void *buf, size_t len) { Md5Context *ctx = (Md5Context *)mc; assert(ctx); assert(buf); assert(len > 0); Md5Update(ctx, buf, (uint32_t)len); }
/* Add data to MD5 */ int CRYPT_MD5_DataAdd(CRYPT_MD5_CTX* md5, const unsigned char* input, unsigned int sz) { if (md5 == NULL || input == NULL) return BAD_FUNC_ARG; Md5Update((Md5*)md5, input, sz); return 0; }
/* Create and store the master secret see page 32, 6.1 */ int MakeMasterSecret(SSL* ssl) { byte shaOutput[SHA_DIGEST_SIZE]; byte md5Input[ENCRYPT_LEN + SHA_DIGEST_SIZE]; byte shaInput[PREFIX + ENCRYPT_LEN + 2 * RAN_LEN]; int i; word32 idx; word32 pmsSz = ssl->arrays.preMasterSz; Md5 md5; Sha sha; #ifndef NO_TLS if (ssl->options.tls) return MakeTlsMasterSecret(ssl); #endif InitMd5(&md5); InitSha(&sha); memcpy(md5Input, ssl->arrays.preMasterSecret, pmsSz); for (i = 0; i < MASTER_ROUNDS; ++i) { byte prefix[PREFIX]; if (!SetPrefix(prefix, i)) { return PREFIX_ERROR; } idx = 0; memcpy(shaInput, prefix, i + 1); idx += i + 1; memcpy(shaInput + idx, ssl->arrays.preMasterSecret, pmsSz); idx += pmsSz; memcpy(shaInput + idx, ssl->arrays.clientRandom, RAN_LEN); idx += RAN_LEN; memcpy(shaInput + idx, ssl->arrays.serverRandom, RAN_LEN); idx += RAN_LEN; ShaUpdate(&sha, shaInput, idx); ShaFinal(&sha, shaOutput); idx = pmsSz; /* preSz */ memcpy(md5Input + idx, shaOutput, SHA_DIGEST_SIZE); idx += SHA_DIGEST_SIZE; Md5Update(&md5, md5Input, idx); Md5Final(&md5, &ssl->arrays.masterSecret[i * MD5_DIGEST_SIZE]); } DeriveKeys(ssl); CleanPreMaster(ssl); return 0; }
static void HmacKeyInnerHash(Hmac* hmac) { if (hmac->macType == MD5) Md5Update(&hmac->hash.md5, (byte*) hmac->ipad, HMAC_BLOCK_SIZE); else if (hmac->macType == SHA) ShaUpdate(&hmac->hash.sha, (byte*) hmac->ipad, HMAC_BLOCK_SIZE); #ifndef NO_SHA256 else if (hmac->macType == SHA256) Sha256Update(&hmac->hash.sha256, (byte*) hmac->ipad, HMAC_BLOCK_SIZE); #endif hmac->innerHashKeyed = 1; }
void HmacUpdate(Hmac* hmac, const byte* msg, word32 length) { if (!hmac->innerHashKeyed) HmacKeyInnerHash(hmac); if (hmac->macType == MD5) Md5Update(&hmac->hash.md5, msg, length); else if (hmac->macType == SHA) ShaUpdate(&hmac->hash.sha, msg, length); #ifndef NO_SHA256 else if (hmac->macType == SHA256) Sha256Update(&hmac->hash.sha256, msg, length); #endif }
int DeriveKeys(SSL* ssl) { int length = 2 * ssl->specs.hash_size + 2 * ssl->specs.key_size + 2 * ssl->specs.iv_size; int rounds = (length + MD5_DIGEST_SIZE - 1 ) / MD5_DIGEST_SIZE, i; byte shaOutput[SHA_DIGEST_SIZE]; byte md5Input[SECRET_LEN + SHA_DIGEST_SIZE]; byte shaInput[KEY_PREFIX + SECRET_LEN + 2 * RAN_LEN]; Md5 md5; Sha sha; byte keyData[KEY_PREFIX * MD5_DIGEST_SIZE]; /* max size */ InitMd5(&md5); InitSha(&sha); XMEMCPY(md5Input, ssl->arrays.masterSecret, SECRET_LEN); for (i = 0; i < rounds; ++i) { int j = i + 1; int idx = j; if (!SetPrefix(shaInput, i)) { return PREFIX_ERROR; } XMEMCPY(shaInput + idx, ssl->arrays.masterSecret, SECRET_LEN); idx += SECRET_LEN; XMEMCPY(shaInput + idx, ssl->arrays.serverRandom, RAN_LEN); idx += RAN_LEN; XMEMCPY(shaInput + idx, ssl->arrays.clientRandom, RAN_LEN); idx += RAN_LEN; ShaUpdate(&sha, shaInput, sizeof(shaInput) - KEY_PREFIX + j); ShaFinal(&sha, shaOutput); XMEMCPY(&md5Input[SECRET_LEN], shaOutput, SHA_DIGEST_SIZE); Md5Update(&md5, md5Input, sizeof(md5Input)); Md5Final(&md5, keyData + i * MD5_DIGEST_SIZE); } return StoreKeys(ssl, keyData); }
int md5str(char *buffer, char *target) { Md5Context md5Context; MD5_HASH md5Hash; uint16_t i; Md5Initialise( &md5Context ); Md5Update( &md5Context, buffer, (uint32_t)strlen(buffer) ); Md5Finalise( &md5Context, &md5Hash ); for( i=0; i<sizeof(md5Hash); i++ ) { sprintf( target+i*2, "%02x", md5Hash.bytes[i] ); } return 0; }
void HmacUpdate(Hmac* hmac, const byte* msg, word32 length) { #ifdef HAVE_CAVIUM if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC) return HmacCaviumUpdate(hmac, msg, length); #endif if (!hmac->innerHashKeyed) HmacKeyInnerHash(hmac); switch (hmac->macType) { #ifndef NO_MD5 case MD5: Md5Update(&hmac->hash.md5, msg, length); break; #endif #ifndef NO_SHA case SHA: ShaUpdate(&hmac->hash.sha, msg, length); break; #endif #ifndef NO_SHA256 case SHA256: Sha256Update(&hmac->hash.sha256, msg, length); break; #endif #ifdef CYASSL_SHA384 case SHA384: Sha384Update(&hmac->hash.sha384, msg, length); break; #endif #ifdef CYASSL_SHA512 case SHA512: Sha512Update(&hmac->hash.sha512, msg, length); break; #endif default: break; } }
void md5 (const void* buf, size_t len, unsigned char result_hash_value [16]) { MD5_CTX context; Md5Init (&context); while (len) { unsigned int update_size = (unsigned int)stl::min (len, (size_t)(unsigned int)-1); Md5Update (&context, (unsigned char*)buf, update_size); buf = (const char*)buf + update_size; len -= update_size; } Md5Final (result_hash_value, &context); }
struct sg_md5_hash sg_md5_easy_buf(void *buf, size_t len, enum sg_md5_fmt fmt) { Md5Context ctx; MD5_HASH hash; struct sg_md5_hash res; assert(buf); assert(len > 0); ZERO(hash, sizeof(struct sg_md5_hash)); Md5Initialise(&ctx); Md5Update(&ctx, buf, (uint32_t)len); Md5Finalise(&ctx, &hash); md5_hash_fmt(&hash, &res, fmt); return res; }
static void HmacKeyInnerHash(Hmac* hmac) { switch (hmac->macType) { #ifndef NO_MD5 case MD5: Md5Update(&hmac->hash.md5, (byte*) hmac->ipad, MD5_BLOCK_SIZE); break; #endif #ifndef NO_SHA case SHA: ShaUpdate(&hmac->hash.sha, (byte*) hmac->ipad, SHA_BLOCK_SIZE); break; #endif #ifndef NO_SHA256 case SHA256: Sha256Update(&hmac->hash.sha256, (byte*) hmac->ipad, SHA256_BLOCK_SIZE); break; #endif #ifdef CYASSL_SHA384 case SHA384: Sha384Update(&hmac->hash.sha384, (byte*) hmac->ipad, SHA384_BLOCK_SIZE); break; #endif #ifdef CYASSL_SHA512 case SHA512: Sha512Update(&hmac->hash.sha512, (byte*) hmac->ipad, SHA512_BLOCK_SIZE); break; #endif default: break; } hmac->innerHashKeyed = 1; }
void bench_md5(void) { Md5 hash; byte digest[MD5_DIGEST_SIZE]; double start, total, persec; int i; InitMd5(&hash); start = current_time(); for(i = 0; i < megs; i++) Md5Update(&hash, plain, sizeof(plain)); Md5Final(&hash, digest); total = current_time() - start; persec = 1 / total * megs; printf("MD5 %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total, persec); }
/* check mcapi md5 against internal */ static int check_md5(void) { CRYPT_MD5_CTX mcMd5; Md5 defMd5; byte mcDigest[CRYPT_MD5_DIGEST_SIZE]; byte defDigest[MD5_DIGEST_SIZE]; CRYPT_MD5_Initialize(&mcMd5); InitMd5(&defMd5); CRYPT_MD5_DataAdd(&mcMd5, ourData, OUR_DATA_SIZE); Md5Update(&defMd5, ourData, OUR_DATA_SIZE); CRYPT_MD5_Finalize(&mcMd5, mcDigest); Md5Final(&defMd5, defDigest); if (memcmp(mcDigest, defDigest, CRYPT_MD5_DIGEST_SIZE) != 0) { printf("md5 final memcmp fialed\n"); return -1; } printf("md5 mcapi test passed\n"); return 0; }
void HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) { byte* ip = (byte*) hmac->ipad; byte* op = (byte*) hmac->opad; word32 i; InitHmac(hmac, type); if (length <= HMAC_BLOCK_SIZE) XMEMCPY(ip, key, length); else { if (hmac->macType == MD5) { Md5Update(&hmac->hash.md5, key, length); Md5Final(&hmac->hash.md5, ip); length = MD5_DIGEST_SIZE; } else if (hmac->macType == SHA) { ShaUpdate(&hmac->hash.sha, key, length); ShaFinal(&hmac->hash.sha, ip); length = SHA_DIGEST_SIZE; } #ifndef NO_SHA256 else if (hmac->macType == SHA256) { Sha256Update(&hmac->hash.sha256, key, length); Sha256Final(&hmac->hash.sha256, ip); length = SHA256_DIGEST_SIZE; } #endif } XMEMSET(ip + length, 0, HMAC_BLOCK_SIZE - length); for(i = 0; i < HMAC_BLOCK_SIZE; i++) { op[i] = ip[i] ^ OPAD; ip[i] ^= IPAD; } }
/** Initator caculates its own expected hash value. @param[in] ChapIdentifier iSCSI CHAP identifier sent by authenticator. @param[in] ChapSecret iSCSI CHAP secret of the authenticator. @param[in] SecretLength The length of iSCSI CHAP secret. @param[in] ChapChallenge The challenge message sent by authenticator. @param[in] ChallengeLength The length of iSCSI CHAP challenge message. @param[out] ChapResponse The calculation of the expected hash value. @retval EFI_SUCCESS The expected hash value was caculatedly successfully. @retval EFI_PROTOCOL_ERROR The length of the secret should be at least the length of the hash value for the hashing algorithm chosen. @retval EFI_PROTOCOL_ERROR MD5 hash operation fail. @retval EFI_OUT_OF_RESOURCES Fail to allocate resource to complete MD5. **/ EFI_STATUS IScsiCHAPCalculateResponse ( IN UINT32 ChapIdentifier, IN CHAR8 *ChapSecret, IN UINT32 SecretLength, IN UINT8 *ChapChallenge, IN UINT32 ChallengeLength, OUT UINT8 *ChapResponse ) { UINTN Md5ContextSize; VOID *Md5Ctx; CHAR8 IdByte[1]; EFI_STATUS Status; if (SecretLength < ISCSI_CHAP_SECRET_MIN_LEN) { return EFI_PROTOCOL_ERROR; } Md5ContextSize = Md5GetContextSize (); Md5Ctx = AllocatePool (Md5ContextSize); if (Md5Ctx == NULL) { return EFI_OUT_OF_RESOURCES; } Status = EFI_PROTOCOL_ERROR; if (!Md5Init (Md5Ctx)) { goto Exit; } // // Hash Identifier - Only calculate 1 byte data (RFC1994) // IdByte[0] = (CHAR8) ChapIdentifier; if (!Md5Update (Md5Ctx, IdByte, 1)) { goto Exit; } // // Hash Secret // if (!Md5Update (Md5Ctx, ChapSecret, SecretLength)) { goto Exit; } // // Hash Challenge received from Target // if (!Md5Update (Md5Ctx, ChapChallenge, ChallengeLength)) { goto Exit; } if (Md5Final (Md5Ctx, ChapResponse)) { Status = EFI_SUCCESS; } Exit: FreePool (Md5Ctx); return Status; }
static int HmacKeyInnerHash(Hmac* hmac) { int ret = 0; switch (hmac->macType) { #ifndef NO_MD5 case MD5: Md5Update(&hmac->hash.md5, (byte*) hmac->ipad, MD5_BLOCK_SIZE); break; #endif #ifndef NO_SHA case SHA: ShaUpdate(&hmac->hash.sha, (byte*) hmac->ipad, SHA_BLOCK_SIZE); break; #endif #ifndef NO_SHA256 case SHA256: ret = Sha256Update(&hmac->hash.sha256, (byte*) hmac->ipad, SHA256_BLOCK_SIZE); if (ret != 0) return ret; break; #endif #ifdef CYASSL_SHA384 case SHA384: ret = Sha384Update(&hmac->hash.sha384, (byte*) hmac->ipad, SHA384_BLOCK_SIZE); if (ret != 0) return ret; break; #endif #ifdef CYASSL_SHA512 case SHA512: ret = Sha512Update(&hmac->hash.sha512, (byte*) hmac->ipad, SHA512_BLOCK_SIZE); if (ret != 0) return ret; break; #endif #ifdef HAVE_BLAKE2 case BLAKE2B_ID: ret = Blake2bUpdate(&hmac->hash.blake2b, (byte*) hmac->ipad,BLAKE2B_BLOCKBYTES); if (ret != 0) return ret; break; #endif default: break; } hmac->innerHashKeyed = 1; return ret; }
int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt, int saltLen, int iterations, int kLen, int hashType, int id) { /* all in bytes instead of bits */ word32 u, v, dLen, pLen, iLen, sLen, totalLen; int dynamic = 0; int ret = 0; int i; byte *D, *S, *P, *I; #ifdef CYASSL_SMALL_STACK byte staticBuffer[1]; /* force dynamic usage */ #else byte staticBuffer[1024]; #endif byte* buffer = staticBuffer; #ifdef CYASSL_SMALL_STACK byte* Ai; byte* B; #else byte Ai[PBKDF_DIGEST_SIZE]; byte B[PBKDF_DIGEST_SIZE]; #endif if (!iterations) iterations = 1; if (hashType == MD5) { v = MD5_BLOCK_SIZE; u = MD5_DIGEST_SIZE; } else if (hashType == SHA) { v = SHA_BLOCK_SIZE; u = SHA_DIGEST_SIZE; } #ifndef NO_SHA256 else if (hashType == SHA256) { v = SHA256_BLOCK_SIZE; u = SHA256_DIGEST_SIZE; } #endif #ifdef CYASSL_SHA512 else if (hashType == SHA512) { v = SHA512_BLOCK_SIZE; u = SHA512_DIGEST_SIZE; } #endif else return BAD_FUNC_ARG; #ifdef CYASSL_SMALL_STACK Ai = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (Ai == NULL) return MEMORY_E; B = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (B == NULL) { XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E; } #endif dLen = v; sLen = v * ((saltLen + v - 1) / v); if (passLen) pLen = v * ((passLen + v - 1) / v); else pLen = 0; iLen = sLen + pLen; totalLen = dLen + sLen + pLen; if (totalLen > sizeof(staticBuffer)) { buffer = (byte*)XMALLOC(totalLen, 0, DYNAMIC_TYPE_KEY); if (buffer == NULL) { #ifdef CYASSL_SMALL_STACK XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(B, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return MEMORY_E; } dynamic = 1; } D = buffer; S = D + dLen; P = S + sLen; I = S; XMEMSET(D, id, dLen); for (i = 0; i < (int)sLen; i++) S[i] = salt[i % saltLen]; for (i = 0; i < (int)pLen; i++) P[i] = passwd[i % passLen]; while (kLen > 0) { word32 currentLen; mp_int B1; if (hashType == MD5) { Md5 md5; InitMd5(&md5); Md5Update(&md5, buffer, totalLen); Md5Final(&md5, Ai); for (i = 1; i < iterations; i++) { Md5Update(&md5, Ai, u); Md5Final(&md5, Ai); } } else if (hashType == SHA) { Sha sha; ret = InitSha(&sha); if (ret != 0) break; ShaUpdate(&sha, buffer, totalLen); ShaFinal(&sha, Ai); for (i = 1; i < iterations; i++) { ShaUpdate(&sha, Ai, u); ShaFinal(&sha, Ai); } } #ifndef NO_SHA256 else if (hashType == SHA256) { Sha256 sha256; ret = InitSha256(&sha256); if (ret != 0) break; ret = Sha256Update(&sha256, buffer, totalLen); if (ret != 0) break; ret = Sha256Final(&sha256, Ai); if (ret != 0) break; for (i = 1; i < iterations; i++) { ret = Sha256Update(&sha256, Ai, u); if (ret != 0) break; ret = Sha256Final(&sha256, Ai); if (ret != 0) break; } } #endif #ifdef CYASSL_SHA512 else if (hashType == SHA512) { Sha512 sha512; ret = InitSha512(&sha512); if (ret != 0) break; ret = Sha512Update(&sha512, buffer, totalLen); if (ret != 0) break; ret = Sha512Final(&sha512, Ai); if (ret != 0) break; for (i = 1; i < iterations; i++) { ret = Sha512Update(&sha512, Ai, u); if (ret != 0) break; ret = Sha512Final(&sha512, Ai); if (ret != 0) break; } } #endif for (i = 0; i < (int)v; i++) B[i] = Ai[i % u]; if (mp_init(&B1) != MP_OKAY) ret = MP_INIT_E; else if (mp_read_unsigned_bin(&B1, B, v) != MP_OKAY) ret = MP_READ_E; else if (mp_add_d(&B1, (mp_digit)1, &B1) != MP_OKAY) ret = MP_ADD_E; if (ret != 0) { mp_clear(&B1); break; } for (i = 0; i < (int)iLen; i += v) { int outSz; mp_int i1; mp_int res; if (mp_init_multi(&i1, &res, NULL, NULL, NULL, NULL) != MP_OKAY) { ret = MP_INIT_E; break; } if (mp_read_unsigned_bin(&i1, I + i, v) != MP_OKAY) ret = MP_READ_E; else if (mp_add(&i1, &B1, &res) != MP_OKAY) ret = MP_ADD_E; else if ( (outSz = mp_unsigned_bin_size(&res)) < 0) ret = MP_TO_E; else { if (outSz > (int)v) { /* take off MSB */ byte tmp[129]; ret = mp_to_unsigned_bin(&res, tmp); XMEMCPY(I + i, tmp + 1, v); } else if (outSz < (int)v) { XMEMSET(I + i, 0, v - outSz); ret = mp_to_unsigned_bin(&res, I + i + v - outSz); } else ret = mp_to_unsigned_bin(&res, I + i); } mp_clear(&i1); mp_clear(&res); if (ret < 0) break; } currentLen = min(kLen, (int)u); XMEMCPY(output, Ai, currentLen); output += currentLen; kLen -= currentLen; mp_clear(&B1); } if (dynamic) XFREE(buffer, 0, DYNAMIC_TYPE_KEY); #ifdef CYASSL_SMALL_STACK XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(B, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; }
int HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) { byte* ip = (byte*) hmac->ipad; byte* op = (byte*) hmac->opad; word32 i, hmac_block_size = 0; int ret; #ifdef HAVE_CAVIUM if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC) return HmacCaviumSetKey(hmac, type, key, length); #endif ret = InitHmac(hmac, type); if (ret != 0) return ret; switch (hmac->macType) { #ifndef NO_MD5 case MD5: { hmac_block_size = MD5_BLOCK_SIZE; if (length <= MD5_BLOCK_SIZE) { XMEMCPY(ip, key, length); } else { Md5Update(&hmac->hash.md5, key, length); Md5Final(&hmac->hash.md5, ip); length = MD5_DIGEST_SIZE; } } break; #endif #ifndef NO_SHA case SHA: { hmac_block_size = SHA_BLOCK_SIZE; if (length <= SHA_BLOCK_SIZE) { XMEMCPY(ip, key, length); } else { ShaUpdate(&hmac->hash.sha, key, length); ShaFinal(&hmac->hash.sha, ip); length = SHA_DIGEST_SIZE; } } break; #endif #ifndef NO_SHA256 case SHA256: { hmac_block_size = SHA256_BLOCK_SIZE; if (length <= SHA256_BLOCK_SIZE) { XMEMCPY(ip, key, length); } else { ret = Sha256Update(&hmac->hash.sha256, key, length); if (ret != 0) return ret; ret = Sha256Final(&hmac->hash.sha256, ip); if (ret != 0) return ret; length = SHA256_DIGEST_SIZE; } } break; #endif #ifdef CYASSL_SHA384 case SHA384: { hmac_block_size = SHA384_BLOCK_SIZE; if (length <= SHA384_BLOCK_SIZE) { XMEMCPY(ip, key, length); } else { ret = Sha384Update(&hmac->hash.sha384, key, length); if (ret != 0) return ret; ret = Sha384Final(&hmac->hash.sha384, ip); if (ret != 0) return ret; length = SHA384_DIGEST_SIZE; } } break; #endif #ifdef CYASSL_SHA512 case SHA512: { hmac_block_size = SHA512_BLOCK_SIZE; if (length <= SHA512_BLOCK_SIZE) { XMEMCPY(ip, key, length); } else { ret = Sha512Update(&hmac->hash.sha512, key, length); if (ret != 0) return ret; ret = Sha512Final(&hmac->hash.sha512, ip); if (ret != 0) return ret; length = SHA512_DIGEST_SIZE; } } break; #endif #ifdef HAVE_BLAKE2 case BLAKE2B_ID: { hmac_block_size = BLAKE2B_BLOCKBYTES; if (length <= BLAKE2B_BLOCKBYTES) { XMEMCPY(ip, key, length); } else { ret = Blake2bUpdate(&hmac->hash.blake2b, key, length); if (ret != 0) return ret; ret = Blake2bFinal(&hmac->hash.blake2b, ip, BLAKE2B_256); if (ret != 0) return ret; length = BLAKE2B_256; } } break; #endif default: return BAD_FUNC_ARG; } if (length < hmac_block_size) XMEMSET(ip + length, 0, hmac_block_size - length); for(i = 0; i < hmac_block_size; i++) { op[i] = ip[i] ^ OPAD; ip[i] ^= IPAD; } return 0; }
/* Create and store the master secret see page 32, 6.1 */ int MakeMasterSecret(SSL* ssl) { byte shaOutput[SHA_DIGEST_SIZE]; byte md5Input[ENCRYPT_LEN + SHA_DIGEST_SIZE]; byte shaInput[PREFIX + ENCRYPT_LEN + 2 * RAN_LEN]; int i, ret; word32 idx; word32 pmsSz = ssl->arrays.preMasterSz; Md5 md5; Sha sha; #ifdef SHOW_SECRETS { int j; printf("pre master secret: "); for (j = 0; j < pmsSz; j++) printf("%02x", ssl->arrays.preMasterSecret[j]); printf("\n"); } #endif #ifndef NO_TLS if (ssl->options.tls) return MakeTlsMasterSecret(ssl); #endif InitMd5(&md5); InitSha(&sha); XMEMCPY(md5Input, ssl->arrays.preMasterSecret, pmsSz); for (i = 0; i < MASTER_ROUNDS; ++i) { byte prefix[PREFIX]; if (!SetPrefix(prefix, i)) { return PREFIX_ERROR; } idx = 0; XMEMCPY(shaInput, prefix, i + 1); idx += i + 1; XMEMCPY(shaInput + idx, ssl->arrays.preMasterSecret, pmsSz); idx += pmsSz; XMEMCPY(shaInput + idx, ssl->arrays.clientRandom, RAN_LEN); idx += RAN_LEN; XMEMCPY(shaInput + idx, ssl->arrays.serverRandom, RAN_LEN); idx += RAN_LEN; ShaUpdate(&sha, shaInput, idx); ShaFinal(&sha, shaOutput); idx = pmsSz; /* preSz */ XMEMCPY(md5Input + idx, shaOutput, SHA_DIGEST_SIZE); idx += SHA_DIGEST_SIZE; Md5Update(&md5, md5Input, idx); Md5Final(&md5, &ssl->arrays.masterSecret[i * MD5_DIGEST_SIZE]); } #ifdef SHOW_SECRETS { int i; printf("master secret: "); for (i = 0; i < SECRET_LEN; i++) printf("%02x", ssl->arrays.masterSecret[i]); printf("\n"); } #endif ret = DeriveKeys(ssl); CleanPreMaster(ssl); return ret; }
int HmacUpdate(Hmac* hmac, const byte* msg, word32 length) { int ret; #ifdef HAVE_CAVIUM if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC) return HmacCaviumUpdate(hmac, msg, length); #endif if (!hmac->innerHashKeyed) { ret = HmacKeyInnerHash(hmac); if (ret != 0) return ret; } switch (hmac->macType) { #ifndef NO_MD5 case MD5: Md5Update(&hmac->hash.md5, msg, length); break; #endif #ifndef NO_SHA case SHA: ShaUpdate(&hmac->hash.sha, msg, length); break; #endif #ifndef NO_SHA256 case SHA256: ret = Sha256Update(&hmac->hash.sha256, msg, length); if (ret != 0) return ret; break; #endif #ifdef CYASSL_SHA384 case SHA384: ret = Sha384Update(&hmac->hash.sha384, msg, length); if (ret != 0) return ret; break; #endif #ifdef CYASSL_SHA512 case SHA512: ret = Sha512Update(&hmac->hash.sha512, msg, length); if (ret != 0) return ret; break; #endif #ifdef HAVE_BLAKE2 case BLAKE2B_ID: ret = Blake2bUpdate(&hmac->hash.blake2b, msg, length); if (ret != 0) return ret; break; #endif default: break; } return 0; }
int HmacFinal(Hmac* hmac, byte* hash) { int ret; #ifdef HAVE_CAVIUM if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC) return HmacCaviumFinal(hmac, hash); #endif if (!hmac->innerHashKeyed) { ret = HmacKeyInnerHash(hmac); if (ret != 0) return ret; } switch (hmac->macType) { #ifndef NO_MD5 case MD5: { Md5Final(&hmac->hash.md5, (byte*) hmac->innerHash); Md5Update(&hmac->hash.md5, (byte*) hmac->opad, MD5_BLOCK_SIZE); Md5Update(&hmac->hash.md5, (byte*) hmac->innerHash, MD5_DIGEST_SIZE); Md5Final(&hmac->hash.md5, hash); } break; #endif #ifndef NO_SHA case SHA: { ShaFinal(&hmac->hash.sha, (byte*) hmac->innerHash); ShaUpdate(&hmac->hash.sha, (byte*) hmac->opad, SHA_BLOCK_SIZE); ShaUpdate(&hmac->hash.sha, (byte*) hmac->innerHash, SHA_DIGEST_SIZE); ShaFinal(&hmac->hash.sha, hash); } break; #endif #ifndef NO_SHA256 case SHA256: { ret = Sha256Final(&hmac->hash.sha256, (byte*) hmac->innerHash); if (ret != 0) return ret; ret = Sha256Update(&hmac->hash.sha256, (byte*) hmac->opad, SHA256_BLOCK_SIZE); if (ret != 0) return ret; ret = Sha256Update(&hmac->hash.sha256, (byte*) hmac->innerHash, SHA256_DIGEST_SIZE); if (ret != 0) return ret; ret = Sha256Final(&hmac->hash.sha256, hash); if (ret != 0) return ret; } break; #endif #ifdef CYASSL_SHA384 case SHA384: { ret = Sha384Final(&hmac->hash.sha384, (byte*) hmac->innerHash); if (ret != 0) return ret; ret = Sha384Update(&hmac->hash.sha384, (byte*) hmac->opad, SHA384_BLOCK_SIZE); if (ret != 0) return ret; ret = Sha384Update(&hmac->hash.sha384, (byte*) hmac->innerHash, SHA384_DIGEST_SIZE); if (ret != 0) return ret; ret = Sha384Final(&hmac->hash.sha384, hash); if (ret != 0) return ret; } break; #endif #ifdef CYASSL_SHA512 case SHA512: { ret = Sha512Final(&hmac->hash.sha512, (byte*) hmac->innerHash); if (ret != 0) return ret; ret = Sha512Update(&hmac->hash.sha512, (byte*) hmac->opad, SHA512_BLOCK_SIZE); if (ret != 0) return ret; ret = Sha512Update(&hmac->hash.sha512, (byte*) hmac->innerHash, SHA512_DIGEST_SIZE); if (ret != 0) return ret; ret = Sha512Final(&hmac->hash.sha512, hash); if (ret != 0) return ret; } break; #endif #ifdef HAVE_BLAKE2 case BLAKE2B_ID: { ret = Blake2bFinal(&hmac->hash.blake2b, (byte*) hmac->innerHash, BLAKE2B_256); if (ret != 0) return ret; ret = Blake2bUpdate(&hmac->hash.blake2b, (byte*) hmac->opad, BLAKE2B_BLOCKBYTES); if (ret != 0) return ret; ret = Blake2bUpdate(&hmac->hash.blake2b, (byte*) hmac->innerHash, BLAKE2B_256); if (ret != 0) return ret; ret = Blake2bFinal(&hmac->hash.blake2b, hash, BLAKE2B_256); if (ret != 0) return ret; } break; #endif default: break; } hmac->innerHashKeyed = 0; return 0; }
OSStatus fogCloudDevFirmwareUpdate(app_context_t* const inContext, MVDOTARequestData_t devOTARequestData) { cloud_if_log_trace(); OSStatus err = kUnknownErr; ecs_ota_flash_params_t ota_flash_params = { MICO_PARTITION_OTA_TEMP, 0x0, }; md5_context md5; unsigned char md5_16[16] = {0}; char *pmd5_32 = NULL; char rom_file_md5[32] = {0}; uint8_t data[SizePerRW] = {0}; uint32_t updateStartAddress = 0; uint32_t readLength = 0; uint32_t i = 0, size = 0; uint32_t romStringLen = 0; // crc16 CRC16_Context contex; cloud_if_log("fogCloudDevFirmwareUpdate: start ..."); //get latest rom version, file_path, md5 cloud_if_log("fogCloudDevFirmwareUpdate: get latest rom version from server ..."); err = FogCloudGetLatestRomVersion(&easyCloudContext); require_noerr_action( err, exit_with_error, cloud_if_log("ERROR: FogCloudGetLatestRomVersion failed! err=%d", err) ); //FW version compare cloud_if_log("currnt_version=%s", inContext->appConfig->fogcloudConfig.romVersion); cloud_if_log("latestRomVersion=%s", easyCloudContext.service_status.latestRomVersion); cloud_if_log("bin_file=%s", easyCloudContext.service_status.bin_file); cloud_if_log("bin_md5=%s", easyCloudContext.service_status.bin_md5); romStringLen = strlen(easyCloudContext.service_status.latestRomVersion) > strlen(inContext->appConfig->fogcloudConfig.romVersion) ? strlen(easyCloudContext.service_status.latestRomVersion):strlen(inContext->appConfig->fogcloudConfig.romVersion); if(0 == strncmp(inContext->appConfig->fogcloudConfig.romVersion, easyCloudContext.service_status.latestRomVersion, romStringLen)) { cloud_if_log("the current firmware version[%s] is up-to-date!", inContext->appConfig->fogcloudConfig.romVersion); inContext->appStatus.fogcloudStatus.RecvRomFileSize = 0; err = kNoErr; goto exit_with_no_error; } cloud_if_log("fogCloudDevFirmwareUpdate: new firmware[%s] found on server, downloading ...", easyCloudContext.service_status.latestRomVersion); inContext->appStatus.fogcloudStatus.isOTAInProgress = true; OTAWillStart(inContext); //get rom data err = FogCloudGetRomData(&easyCloudContext, ota_flash_params); require_noerr_action( err, exit_with_error, cloud_if_log("ERROR: FogCloudGetRomData failed! err=%d", err) ); //------------------------------ OTA DATA VERIFY ----------------------------- // md5 init InitMd5(&md5); CRC16_Init( &contex ); memset(rom_file_md5, 0, 32); memset(data, 0xFF, SizePerRW); updateStartAddress = ota_flash_params.update_offset; size = (easyCloudContext.service_status.bin_file_size)/SizePerRW; // read flash, md5 update for(i = 0; i <= size; i++) { if( i == size ) { if( (easyCloudContext.service_status.bin_file_size)%SizePerRW ) { readLength = (easyCloudContext.service_status.bin_file_size)%SizePerRW; } else { break; } } else { readLength = SizePerRW; } err = MicoFlashRead(ota_flash_params.update_partion, &updateStartAddress, data, readLength); require_noerr(err, exit_with_error); Md5Update(&md5, (uint8_t *)data, readLength); CRC16_Update( &contex, data, readLength ); } // read done, calc MD5 Md5Final(&md5, md5_16); CRC16_Final( &contex, &ota_crc ); pmd5_32 = ECS_DataToHexStringLowercase(md5_16, sizeof(md5_16)); //convert hex data to hex string cloud_if_log("ota_data_in_flash_md5[%d]=%s", strlen(pmd5_32), pmd5_32); if (NULL != pmd5_32) { strncpy(rom_file_md5, pmd5_32, strlen(pmd5_32)); free(pmd5_32); pmd5_32 = NULL; } else { err = kNoMemoryErr; goto exit_with_error; } // check md5 if(0 != strncmp( easyCloudContext.service_status.bin_md5, (char*)&(rom_file_md5[0]), strlen( easyCloudContext.service_status.bin_md5))) { cloud_if_log("ERROR: ota data wrote in flash md5 checksum err!!!"); err = kChecksumErr; goto exit_with_error; } else { cloud_if_log("OTA data in flash md5 check success, crc16=%d.", ota_crc); } //---------------------------------------------------------------------------- //update rom version in flash cloud_if_log("fogCloudDevFirmwareUpdate: return rom version && file size."); mico_rtos_lock_mutex(&inContext->mico_context->flashContentInRam_mutex); memset(inContext->appConfig->fogcloudConfig.romVersion, 0, MAX_SIZE_FW_VERSION); strncpy(inContext->appConfig->fogcloudConfig.romVersion, easyCloudContext.service_status.latestRomVersion, strlen(easyCloudContext.service_status.latestRomVersion)); inContext->appStatus.fogcloudStatus.RecvRomFileSize = easyCloudContext.service_status.bin_file_size; err = mico_system_context_update(inContext->mico_context); mico_rtos_unlock_mutex(&inContext->mico_context->flashContentInRam_mutex); OTASuccess(inContext); err = kNoErr; goto exit_with_no_error; exit_with_no_error: cloud_if_log("fogCloudDevFirmwareUpdate exit with no error."); inContext->appStatus.fogcloudStatus.isOTAInProgress = false; return err; exit_with_error: cloud_if_log("fogCloudDevFirmwareUpdate exit with err=%d.", err); OTAFailed(inContext); inContext->appStatus.fogcloudStatus.isOTAInProgress = false; return err; }
int MD5_Update(MD5_CTX *md5, void *input, unsigned long sz) { Md5Update(md5, input, (word32)sz); return 1; }