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; }
void BuildTlsFinished(CYASSL* ssl, Hashes* hashes, const byte* sender) { const byte* side; byte handshake_hash[HSHASH_SZ]; word32 hashSz = FINISHED_SZ; #ifndef NO_OLD_TLS Md5Final(&ssl->hashMd5, handshake_hash); ShaFinal(&ssl->hashSha, &handshake_hash[MD5_DIGEST_SIZE]); #endif if (IsAtLeastTLSv1_2(ssl)) { #ifndef NO_SHA256 if (ssl->specs.mac_algorithm <= sha256_mac) { Sha256Final(&ssl->hashSha256, handshake_hash); hashSz = SHA256_DIGEST_SIZE; } #endif #ifdef CYASSL_SHA384 if (ssl->specs.mac_algorithm == sha384_mac) { Sha384Final(&ssl->hashSha384, handshake_hash); hashSz = SHA384_DIGEST_SIZE; } #endif } if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0) side = tls_client; else side = tls_server; PRF((byte*)hashes, TLS_FINISHED_SZ, ssl->arrays->masterSecret, SECRET_LEN, side, FINISHED_LABEL_SZ, handshake_hash, hashSz, IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm); }
/* check mcapi sha256 against internal */ static int check_sha256(void) { CRYPT_SHA256_CTX mcSha256; Sha256 defSha256; int ret; byte mcDigest[CRYPT_SHA256_DIGEST_SIZE]; byte defDigest[SHA256_DIGEST_SIZE]; CRYPT_SHA256_Initialize(&mcSha256); ret = InitSha256(&defSha256); if (ret != 0) { printf("sha256 init default failed\n"); return -1; } CRYPT_SHA256_DataAdd(&mcSha256, ourData, OUR_DATA_SIZE); Sha256Update(&defSha256, ourData, OUR_DATA_SIZE); CRYPT_SHA256_Finalize(&mcSha256, mcDigest); Sha256Final(&defSha256, defDigest); if (memcmp(mcDigest, defDigest, CRYPT_SHA256_DIGEST_SIZE) != 0) { printf("sha256 final memcmp fialed\n"); return -1; } printf("sha256 mcapi test passed\n"); return 0; }
/* Get SHA-256 Final into digest */ int CRYPT_SHA256_Finalize(CRYPT_SHA256_CTX* sha256, unsigned char* digest) { if (sha256 == NULL || digest == NULL) return BAD_FUNC_ARG; return Sha256Final((Sha256*)sha256, digest); }
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */ static int Hash_gen(RNG* rng, byte* out, word32 outSz, const byte* V) { byte data[DRBG_SEED_LEN]; int i; int len = (outSz / OUTPUT_BLOCK_LEN) + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0); XMEMCPY(data, V, sizeof(data)); for (i = 0; i < len; i++) { if (InitSha256(&rng->sha) != 0 || Sha256Update(&rng->sha, data, sizeof(data)) != 0 || Sha256Final(&rng->sha, rng->digest) != 0) { return DRBG_FAILURE; } if (outSz > OUTPUT_BLOCK_LEN) { XMEMCPY(out, rng->digest, OUTPUT_BLOCK_LEN); outSz -= OUTPUT_BLOCK_LEN; out += OUTPUT_BLOCK_LEN; array_add_one(data, DRBG_SEED_LEN); } else { XMEMCPY(out, rng->digest, outSz); } } XMEMSET(data, 0, sizeof(data)); return DRBG_SUCCESS; }
int Sha256Hash(const byte* data, word32 len, byte* hash) { int ret = 0; #ifdef CYASSL_SMALL_STACK Sha256* sha256; #else Sha256 sha256[1]; #endif #ifdef CYASSL_SMALL_STACK sha256 = (Sha256*)XMALLOC(sizeof(Sha256), NULL, DYNAMIC_TYPE_TMP_BUFFER); if (sha256 == NULL) return MEMORY_E; #endif if ((ret = InitSha256(sha256)) != 0) { CYASSL_MSG("InitSha256 failed"); } else if ((ret = Sha256Update(sha256, data, len)) != 0) { CYASSL_MSG("Sha256Update failed"); } else if ((ret = Sha256Final(sha256, hash)) != 0) { CYASSL_MSG("Sha256Final failed"); } #ifdef CYASSL_SMALL_STACK XFREE(sha256, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; }
void file_test(const char* file, byte* check) { FILE* f; int i = 0, j; Sha256 sha256; byte buf[1024]; byte shasum[SHA256_DIGEST_SIZE]; InitSha256(&sha256); if( !( f = fopen( file, "rb" ) )) { printf("Can't open %s\n", file); return; } while( ( i = (int)fread(buf, 1, sizeof(buf), f )) > 0 ) Sha256Update(&sha256, buf, i); Sha256Final(&sha256, shasum); memcpy(check, shasum, sizeof(shasum)); for(j = 0; j < SHA256_DIGEST_SIZE; ++j ) printf( "%02x", shasum[j] ); printf(" %s\n", file); fclose(f); }
static int Hash_gen(RNG* rng, byte* out, word32 outSz, byte* V) { byte data[DBRG_SEED_LEN]; int i, ret; int len = (outSz / SHA256_DIGEST_SIZE) + ((outSz % SHA256_DIGEST_SIZE) ? 1 : 0); XMEMCPY(data, V, sizeof(data)); for (i = 0; i < len; i++) { ret = InitSha256(&rng->sha); if (ret != 0) return ret; Sha256Update(&rng->sha, data, sizeof(data)); Sha256Final(&rng->sha, rng->digest); if (outSz > SHA256_DIGEST_SIZE) { XMEMCPY(out, rng->digest, SHA256_DIGEST_SIZE); outSz -= SHA256_DIGEST_SIZE; out += SHA256_DIGEST_SIZE; array_add_one(data, DBRG_SEED_LEN); } else { XMEMCPY(out, rng->digest, outSz); } } XMEMSET(data, 0, sizeof(data)); return 0; }
void bench_sha256(void) { Sha256 hash; byte digest[SHA256_DIGEST_SIZE]; double start, total, persec; int i; InitSha256(&hash); start = current_time(1); for(i = 0; i < numBlocks; i++) Sha256Update(&hash, plain, sizeof(plain)); Sha256Final(&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("SHA-256 %d %s took %5.3f seconds, %6.2f MB/s\n", numBlocks, blockType, total, persec); }
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */ static int Hash_gen(DRBG* drbg, byte* out, word32 outSz, const byte* V) { byte data[DRBG_SEED_LEN]; int i; int len; word32 checkBlock; /* Special case: outSz is 0 and out is NULL. Generate a block to save for * the continuous test. */ if (outSz == 0) outSz = 1; len = (outSz / OUTPUT_BLOCK_LEN) + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0); XMEMCPY(data, V, sizeof(data)); for (i = 0; i < len; i++) { if (InitSha256(&drbg->sha) != 0 || Sha256Update(&drbg->sha, data, sizeof(data)) != 0 || Sha256Final(&drbg->sha, drbg->digest) != 0) { return DRBG_FAILURE; } checkBlock = *(word32*)drbg->digest; if (drbg->reseedCtr > 1 && checkBlock == drbg->lastBlock) { if (drbg->matchCount == 1) { return DRBG_CONT_FAILURE; } else { if (i == len) { len++; } drbg->matchCount = 1; } } else { drbg->matchCount = 0; drbg->lastBlock = checkBlock; } if (outSz >= OUTPUT_BLOCK_LEN) { XMEMCPY(out, drbg->digest, OUTPUT_BLOCK_LEN); outSz -= OUTPUT_BLOCK_LEN; out += OUTPUT_BLOCK_LEN; array_add_one(data, DRBG_SEED_LEN); } else if (out != NULL && outSz != 0) { XMEMCPY(out, drbg->digest, outSz); outSz = 0; } } XMEMSET(data, 0, sizeof(data)); return DRBG_SUCCESS; }
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */ static int Hash_df(DRBG* drbg, byte* out, word32 outSz, byte type, const byte* inA, word32 inASz, const byte* inB, word32 inBSz) { byte ctr; int i; int len; word32 bits = (outSz * 8); /* reverse byte order */ #ifdef LITTLE_ENDIAN_ORDER bits = ByteReverseWord32(bits); #endif len = (outSz / OUTPUT_BLOCK_LEN) + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0); for (i = 0, ctr = 1; i < len; i++, ctr++) { if (InitSha256(&drbg->sha) != 0) return DRBG_FAILURE; if (Sha256Update(&drbg->sha, &ctr, sizeof(ctr)) != 0) return DRBG_FAILURE; if (Sha256Update(&drbg->sha, (byte*)&bits, sizeof(bits)) != 0) return DRBG_FAILURE; /* churning V is the only string that doesn't have * the type added */ if (type != drbgInitV) if (Sha256Update(&drbg->sha, &type, sizeof(type)) != 0) return DRBG_FAILURE; if (Sha256Update(&drbg->sha, inA, inASz) != 0) return DRBG_FAILURE; if (inB != NULL && inBSz > 0) if (Sha256Update(&drbg->sha, inB, inBSz) != 0) return DRBG_FAILURE; if (Sha256Final(&drbg->sha, drbg->digest) != 0) return DRBG_FAILURE; if (outSz > OUTPUT_BLOCK_LEN) { XMEMCPY(out, drbg->digest, OUTPUT_BLOCK_LEN); outSz -= OUTPUT_BLOCK_LEN; out += OUTPUT_BLOCK_LEN; } else { XMEMCPY(out, drbg->digest, outSz); } } return DRBG_SUCCESS; }
void Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */ size_t tmplen, unsigned char *sha256sum /* output */, size_t unused) { Sha256 SHA256pw; (void)unused; InitSha256(&SHA256pw); Sha256Update(&SHA256pw, tmp, (word32)tmplen); Sha256Final(&SHA256pw, sha256sum); }
int sha256_test(void) { Sha256 sha; byte hash[SHA256_DIGEST_SIZE]; testVector a, b; testVector test_sha[2]; int ret; int times = sizeof(test_sha) / sizeof(struct testVector), i; a.input = "abc"; a.output = "\xBA\x78\x16\xBF\x8F\x01\xCF\xEA\x41\x41\x40\xDE\x5D\xAE\x22" "\x23\xB0\x03\x61\xA3\x96\x17\x7A\x9C\xB4\x10\xFF\x61\xF2\x00" "\x15\xAD"; a.inLen = strlen(a.input); a.outLen = strlen(a.output); b.input = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; b.output = "\x24\x8D\x6A\x61\xD2\x06\x38\xB8\xE5\xC0\x26\x93\x0C\x3E\x60" "\x39\xA3\x3C\xE4\x59\x64\xFF\x21\x67\xF6\xEC\xED\xD4\x19\xDB" "\x06\xC1"; b.inLen = strlen(b.input); b.outLen = strlen(b.output); test_sha[0] = a; test_sha[1] = b; ret = InitSha256(&sha); if (ret != 0) return ret; for (i = 0; i < times; ++i) { ret = Sha256Update(&sha, (byte*)test_sha[i].input,(word32)test_sha[i].inLen); if (ret != 0) return ret; ret = Sha256Final(&sha, hash); if (ret != 0) return ret; if (memcmp(hash, test_sha[i].output, SHA256_DIGEST_SIZE) != 0) return -10 - i; } return 0; }
/** Complete hash sequence complete. @param HashHandle Hash handle. @param DigestList Digest list. @retval EFI_SUCCESS Hash sequence complete and DigestList is returned. **/ EFI_STATUS EFIAPI Sha256HashFinal ( IN HASH_HANDLE HashHandle, OUT TPML_DIGEST_VALUES *DigestList ) { UINT8 Digest[SHA256_DIGEST_SIZE]; VOID *Sha256Ctx; Sha256Ctx = (VOID *)HashHandle; Sha256Final (Sha256Ctx, Digest); FreePool (Sha256Ctx); Tpm2SetSha256ToDigestList (DigestList, Digest); return EFI_SUCCESS; }
static int Hash_df(RNG* rng, byte* out, word32 outSz, byte type, byte* inA, word32 inASz, byte* inB, word32 inBSz, byte* inC, word32 inCSz) { byte ctr; int i; int len; word32 bits = (outSz * 8); /* reverse byte order */ #ifdef LITTLE_ENDIAN_ORDER bits = ByteReverseWord32(bits); #endif len = (outSz / SHA256_DIGEST_SIZE) + ((outSz % SHA256_DIGEST_SIZE) ? 1 : 0); for (i = 0, ctr = 1; i < len; i++, ctr++) { if (InitSha256(&rng->sha) != 0) return DBRG_ERROR; Sha256Update(&rng->sha, &ctr, sizeof(ctr)); Sha256Update(&rng->sha, (byte*)&bits, sizeof(bits)); /* churning V is the only string that doesn't have * the type added */ if (type != dbrgInitV) Sha256Update(&rng->sha, &type, sizeof(type)); Sha256Update(&rng->sha, inA, inASz); if (inB != NULL && inBSz > 0) Sha256Update(&rng->sha, inB, inBSz); if (inC != NULL && inCSz > 0) Sha256Update(&rng->sha, inC, inCSz); Sha256Final(&rng->sha, rng->digest); if (outSz > SHA256_DIGEST_SIZE) { XMEMCPY(out, rng->digest, SHA256_DIGEST_SIZE); outSz -= SHA256_DIGEST_SIZE; out += SHA256_DIGEST_SIZE; } else { XMEMCPY(out, rng->digest, outSz); } } return DBRG_SUCCESS; }
void bench_sha256(void) { Sha256 hash; byte digest[SHA256_DIGEST_SIZE]; double start, total, persec; int i; InitSha256(&hash); start = current_time(); for(i = 0; i < megs; i++) Sha256Update(&hash, plain, sizeof(plain)); Sha256Final(&hash, digest); total = current_time() - start; persec = 1 / total * megs; printf("SHA-256 %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total, persec); }
void bench_sha256(void) { Sha256 hash; byte digest[SHA256_DIGEST_SIZE]; double start, total, persec; int i, ret; ret = InitSha256(&hash); if (ret != 0) { printf("InitSha256 failed, ret = %d\n", ret); return; } start = current_time(1); for(i = 0; i < numBlocks; i++) { ret = Sha256Update(&hash, plain, sizeof(plain)); if (ret != 0) { printf("Sha256Update failed, ret = %d\n", ret); return; } } ret = Sha256Final(&hash, digest); if (ret != 0) { printf("Sha256Final failed, ret = %d\n", ret); return; } total = current_time(0) - start; persec = 1 / total * numBlocks; #ifdef BENCH_EMBEDDED /* since using kB, convert to MB/s */ persec = persec / 1024; #endif printf("SHA-256 %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks, blockType, total, persec); }
void BuildTlsFinished(SSL* ssl, Hashes* hashes, const byte* sender) { const byte* side; byte handshake_hash[FINISHED_SZ]; word32 hashSz = FINISHED_SZ; Md5Final(&ssl->hashMd5, handshake_hash); ShaFinal(&ssl->hashSha, &handshake_hash[MD5_DIGEST_SIZE]); #ifndef NO_SHA256 if (IsAtLeastTLSv1_2(ssl)) { Sha256Final(&ssl->hashSha256, handshake_hash); hashSz = SHA256_DIGEST_SIZE; } #endif if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0) side = tls_client; else side = tls_server; PRF(hashes->md5, TLS_FINISHED_SZ, ssl->arrays.masterSecret, SECRET_LEN, side, FINISHED_LABEL_SZ, handshake_hash, hashSz, IsAtLeastTLSv1_2(ssl)); }
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; } }
/** Verify data payload with AuthInfo in EFI_CERT_TYPE_RSA2048_SHA256 type. Follow the steps in UEFI2.2. @param[in] VirtualMode The current calling mode for this function. @param[in] Global The context of this Extended SAL Variable Services Class call. @param[in] Data The pointer to data with AuthInfo. @param[in] DataSize The size of Data. @param[in] PubKey The public key used for verification. @retval EFI_INVALID_PARAMETER Invalid parameter. @retval EFI_SECURITY_VIOLATION Authentication failed. @retval EFI_SUCCESS Authentication successful. **/ EFI_STATUS VerifyDataPayload ( IN BOOLEAN VirtualMode, IN ESAL_VARIABLE_GLOBAL *Global, IN UINT8 *Data, IN UINTN DataSize, IN UINT8 *PubKey ) { BOOLEAN Status; EFI_VARIABLE_AUTHENTICATION *CertData; EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock; UINT8 Digest[SHA256_DIGEST_SIZE]; VOID *Rsa; VOID *HashContext; Rsa = NULL; CertData = NULL; CertBlock = NULL; if (Data == NULL || PubKey == NULL) { return EFI_INVALID_PARAMETER; } CertData = (EFI_VARIABLE_AUTHENTICATION *) Data; CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256 *) (CertData->AuthInfo.CertData); // // wCertificateType should be WIN_CERT_TYPE_EFI_GUID. // Cert type should be EFI_CERT_TYPE_RSA2048_SHA256. // if ((CertData->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) || !CompareGuid (&CertData->AuthInfo.CertType, Global->CertRsa2048Sha256Guid[VirtualMode]) ) { // // Invalid AuthInfo type, return EFI_SECURITY_VIOLATION. // return EFI_SECURITY_VIOLATION; } // // Hash data payload with SHA256. // ZeroMem (Digest, SHA256_DIGEST_SIZE); HashContext = Global->HashContext[VirtualMode]; Status = Sha256Init (HashContext); if (!Status) { goto Done; } Status = Sha256Update (HashContext, Data + AUTHINFO_SIZE, (UINTN) (DataSize - AUTHINFO_SIZE)); if (!Status) { goto Done; } // // Hash Monotonic Count. // Status = Sha256Update (HashContext, &CertData->MonotonicCount, sizeof (UINT64)); if (!Status) { goto Done; } Status = Sha256Final (HashContext, Digest); if (!Status) { goto Done; } // // Generate & Initialize RSA Context. // Rsa = RsaNew (); ASSERT (Rsa != NULL); // // Set RSA Key Components. // NOTE: Only N and E are needed to be set as RSA public key for signature verification. // Status = RsaSetKey (Rsa, RsaKeyN, PubKey, EFI_CERT_TYPE_RSA2048_SIZE); if (!Status) { goto Done; } Status = RsaSetKey (Rsa, RsaKeyE, mRsaE, sizeof (mRsaE)); if (!Status) { goto Done; } // // Verify the signature. // Status = RsaPkcs1Verify ( Rsa, Digest, SHA256_DIGEST_SIZE, CertBlock->Signature, EFI_CERT_TYPE_RSA2048_SHA256_SIZE ); Done: if (Rsa != NULL) { RsaFree (Rsa); } if (Status) { return EFI_SUCCESS; } else { return EFI_SECURITY_VIOLATION; } }
void HmacFinal(Hmac* hmac, byte* hash) { #ifdef HAVE_CAVIUM if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC) return HmacCaviumFinal(hmac, hash); #endif if (!hmac->innerHashKeyed) HmacKeyInnerHash(hmac); 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: { Sha256Final(&hmac->hash.sha256, (byte*) hmac->innerHash); Sha256Update(&hmac->hash.sha256, (byte*) hmac->opad, SHA256_BLOCK_SIZE); Sha256Update(&hmac->hash.sha256, (byte*) hmac->innerHash, SHA256_DIGEST_SIZE); Sha256Final(&hmac->hash.sha256, hash); } break; #endif #ifdef CYASSL_SHA384 case SHA384: { Sha384Final(&hmac->hash.sha384, (byte*) hmac->innerHash); Sha384Update(&hmac->hash.sha384, (byte*) hmac->opad, SHA384_BLOCK_SIZE); Sha384Update(&hmac->hash.sha384, (byte*) hmac->innerHash, SHA384_DIGEST_SIZE); Sha384Final(&hmac->hash.sha384, hash); } break; #endif #ifdef CYASSL_SHA512 case SHA512: { Sha512Final(&hmac->hash.sha512, (byte*) hmac->innerHash); Sha512Update(&hmac->hash.sha512, (byte*) hmac->opad, SHA512_BLOCK_SIZE); Sha512Update(&hmac->hash.sha512, (byte*) hmac->innerHash, SHA512_DIGEST_SIZE); Sha512Final(&hmac->hash.sha512, hash); } break; #endif default: break; } hmac->innerHashKeyed = 0; }
/** Extraction handler tries to extract raw data from the input guided section. It also does authentication check for RSA 2048 SHA 256 signature in the input guided section. It first checks whether the input guid section is supported. If not, EFI_INVALID_PARAMETER will return. @param InputSection Buffer containing the input GUIDed section to be processed. @param OutputBuffer Buffer to contain the output raw data allocated by the caller. @param ScratchBuffer A pointer to a caller-allocated buffer for function internal use. @param AuthenticationStatus A pointer to a caller-allocated UINT32 that indicates the authentication status of the output buffer. @retval EFI_SUCCESS Section Data and Auth Status is extracted successfully. @retval EFI_INVALID_PARAMETER The GUID in InputSection does not match this instance guid. **/ EFI_STATUS EFIAPI Rsa2048Sha256GuidedSectionHandler ( IN CONST VOID *InputSection, OUT VOID **OutputBuffer, IN VOID *ScratchBuffer, OPTIONAL OUT UINT32 *AuthenticationStatus ) { EFI_STATUS Status; UINT32 OutputBufferSize; VOID *DummyInterface; EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlockRsa2048Sha256; BOOLEAN CryptoStatus; UINT8 Digest[SHA256_DIGEST_SIZE]; UINT8 *PublicKey; UINTN PublicKeyBufferSize; VOID *HashContext; VOID *Rsa; HashContext = NULL; Rsa = NULL; if (IS_SECTION2 (InputSection)) { // // Check whether the input guid section is recognized. // if (!CompareGuid ( &gEfiCertTypeRsa2048Sha256Guid, &(((EFI_GUID_DEFINED_SECTION2 *)InputSection)->SectionDefinitionGuid))) { return EFI_INVALID_PARAMETER; } // // Get the RSA 2048 SHA 256 information. // CertBlockRsa2048Sha256 = &((RSA_2048_SHA_256_SECTION2_HEADER *) InputSection)->CertBlockRsa2048Sha256; OutputBufferSize = SECTION2_SIZE (InputSection) - sizeof (RSA_2048_SHA_256_SECTION2_HEADER); if ((((EFI_GUID_DEFINED_SECTION *)InputSection)->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) { PERF_START (NULL, "RsaCopy", "DXE", 0); CopyMem (*OutputBuffer, (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION2_HEADER), OutputBufferSize); PERF_END (NULL, "RsaCopy", "DXE", 0); } else { *OutputBuffer = (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION2_HEADER); } // // Implicitly RSA 2048 SHA 256 GUIDed section should have STATUS_VALID bit set // ASSERT ((((EFI_GUID_DEFINED_SECTION2 *)InputSection)->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) != 0); *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED; } else { // // Check whether the input guid section is recognized. // if (!CompareGuid ( &gEfiCertTypeRsa2048Sha256Guid, &(((EFI_GUID_DEFINED_SECTION *)InputSection)->SectionDefinitionGuid))) { return EFI_INVALID_PARAMETER; } // // Get the RSA 2048 SHA 256 information. // CertBlockRsa2048Sha256 = &((RSA_2048_SHA_256_SECTION_HEADER *)InputSection)->CertBlockRsa2048Sha256; OutputBufferSize = SECTION_SIZE (InputSection) - sizeof (RSA_2048_SHA_256_SECTION_HEADER); if ((((EFI_GUID_DEFINED_SECTION *)InputSection)->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) { PERF_START (NULL, "RsaCopy", "DXE", 0); CopyMem (*OutputBuffer, (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION_HEADER), OutputBufferSize); PERF_END (NULL, "RsaCopy", "DXE", 0); } else { *OutputBuffer = (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION_HEADER); } // // Implicitly RSA 2048 SHA 256 GUIDed section should have STATUS_VALID bit set // ASSERT ((((EFI_GUID_DEFINED_SECTION *) InputSection)->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) != 0); *AuthenticationStatus = EFI_AUTH_STATUS_IMAGE_SIGNED; } // // Check whether there exists EFI_SECURITY_POLICY_PROTOCOL_GUID. // Status = gBS->LocateProtocol (&gEfiSecurityPolicyProtocolGuid, NULL, &DummyInterface); if (!EFI_ERROR (Status)) { // // If SecurityPolicy Protocol exist, AUTH platform override bit is set. // *AuthenticationStatus |= EFI_AUTH_STATUS_PLATFORM_OVERRIDE; return EFI_SUCCESS; } // // All paths from here return EFI_SUCESS and result is returned in AuthenticationStatus // Status = EFI_SUCCESS; // // Fail if the HashType is not SHA 256 // if (!CompareGuid (&gEfiHashAlgorithmSha256Guid, &CertBlockRsa2048Sha256->HashType)) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: HASH type of section is not supported\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Allocate hash context buffer required for SHA 256 // HashContext = AllocatePool (Sha256GetContextSize ()); if (HashContext == NULL) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Can not allocate hash context\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Hash public key from data payload with SHA256. // ZeroMem (Digest, SHA256_DIGEST_SIZE); CryptoStatus = Sha256Init (HashContext); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Init() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } CryptoStatus = Sha256Update (HashContext, &CertBlockRsa2048Sha256->PublicKey, sizeof(CertBlockRsa2048Sha256->PublicKey)); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Update() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } CryptoStatus = Sha256Final (HashContext, Digest); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Final() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Fail if the PublicKey is not one of the public keys in PcdRsa2048Sha256PublicKeyBuffer // PublicKey = (UINT8 *)PcdGetPtr (PcdRsa2048Sha256PublicKeyBuffer); DEBUG ((DEBUG_VERBOSE, "DxePcdRsa2048Sha256: PublicKeyBuffer = %p\n", PublicKey)); ASSERT (PublicKey != NULL); DEBUG ((DEBUG_VERBOSE, "DxePcdRsa2048Sha256: PublicKeyBuffer Token = %08x\n", PcdToken (PcdRsa2048Sha256PublicKeyBuffer))); PublicKeyBufferSize = LibPcdGetExSize (&gEfiSecurityPkgTokenSpaceGuid, PcdToken (PcdRsa2048Sha256PublicKeyBuffer)); DEBUG ((DEBUG_VERBOSE, "DxePcdRsa2048Sha256: PublicKeyBuffer Size = %08x\n", PublicKeyBufferSize)); ASSERT ((PublicKeyBufferSize % SHA256_DIGEST_SIZE) == 0); CryptoStatus = FALSE; while (PublicKeyBufferSize != 0) { if (CompareMem (Digest, PublicKey, SHA256_DIGEST_SIZE) == 0) { CryptoStatus = TRUE; break; } PublicKey = PublicKey + SHA256_DIGEST_SIZE; PublicKeyBufferSize = PublicKeyBufferSize - SHA256_DIGEST_SIZE; } if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Public key in section is not supported\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Generate & Initialize RSA Context. // Rsa = RsaNew (); if (Rsa == NULL) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaNew() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Set RSA Key Components. // NOTE: Only N and E are needed to be set as RSA public key for signature verification. // CryptoStatus = RsaSetKey (Rsa, RsaKeyN, CertBlockRsa2048Sha256->PublicKey, sizeof(CertBlockRsa2048Sha256->PublicKey)); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaSetKey(RsaKeyN) failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } CryptoStatus = RsaSetKey (Rsa, RsaKeyE, mRsaE, sizeof (mRsaE)); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaSetKey(RsaKeyE) failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Hash data payload with SHA256. // ZeroMem (Digest, SHA256_DIGEST_SIZE); CryptoStatus = Sha256Init (HashContext); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Init() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } PERF_START (NULL, "RsaShaData", "DXE", 0); CryptoStatus = Sha256Update (HashContext, *OutputBuffer, OutputBufferSize); PERF_END (NULL, "RsaShaData", "DXE", 0); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Update() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } CryptoStatus = Sha256Final (HashContext, Digest); if (!CryptoStatus) { DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Final() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; goto Done; } // // Verify the RSA 2048 SHA 256 signature. // PERF_START (NULL, "RsaVerify", "DXE", 0); CryptoStatus = RsaPkcs1Verify ( Rsa, Digest, SHA256_DIGEST_SIZE, CertBlockRsa2048Sha256->Signature, sizeof (CertBlockRsa2048Sha256->Signature) ); PERF_END (NULL, "RsaVerify", "DXE", 0); if (!CryptoStatus) { // // If RSA 2048 SHA 256 signature verification fails, AUTH tested failed bit is set. // DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaPkcs1Verify() failed\n")); *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED; } Done: // // Free allocated resources used to perform RSA 2048 SHA 256 signature verification // if (Rsa != NULL) { RsaFree (Rsa); } if (HashContext != NULL) { FreePool (HashContext); } DEBUG ((DEBUG_VERBOSE, "DxeRsa2048Sha256: Status = %r AuthenticationStatus = %08x\n", Status, *AuthenticationStatus)); return Status; }
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; }
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; }
/** Calculates the hash of the given data based on the specified hash GUID. @param[in] Data Pointer to the data buffer to be hashed. @param[in] DataSize The size of data buffer in bytes. @param[in] CertGuid The GUID to identify the hash algorithm to be used. @param[out] HashValue Pointer to a buffer that receives the hash result. @retval TRUE Data hash calculation succeeded. @retval FALSE Data hash calculation failed. **/ BOOLEAN CalculateDataHash ( IN VOID *Data, IN UINTN DataSize, IN EFI_GUID *CertGuid, OUT UINT8 *HashValue ) { BOOLEAN Status; VOID *HashCtx; UINTN CtxSize; Status = FALSE; HashCtx = NULL; if (CompareGuid (CertGuid, &gEfiCertSha1Guid)) { // // SHA-1 Hash // CtxSize = Sha1GetContextSize (); HashCtx = AllocatePool (CtxSize); if (HashCtx == NULL) { goto _Exit; } Status = Sha1Init (HashCtx); Status = Sha1Update (HashCtx, Data, DataSize); Status = Sha1Final (HashCtx, HashValue); } else if (CompareGuid (CertGuid, &gEfiCertSha256Guid)) { // // SHA256 Hash // CtxSize = Sha256GetContextSize (); HashCtx = AllocatePool (CtxSize); if (HashCtx == NULL) { goto _Exit; } Status = Sha256Init (HashCtx); Status = Sha256Update (HashCtx, Data, DataSize); Status = Sha256Final (HashCtx, HashValue); } else if (CompareGuid (CertGuid, &gEfiCertSha384Guid)) { // // SHA384 Hash // CtxSize = Sha384GetContextSize (); HashCtx = AllocatePool (CtxSize); if (HashCtx == NULL) { goto _Exit; } Status = Sha384Init (HashCtx); Status = Sha384Update (HashCtx, Data, DataSize); Status = Sha384Final (HashCtx, HashValue); } else if (CompareGuid (CertGuid, &gEfiCertSha512Guid)) { // // SHA512 Hash // CtxSize = Sha512GetContextSize (); HashCtx = AllocatePool (CtxSize); if (HashCtx == NULL) { goto _Exit; } Status = Sha512Init (HashCtx); Status = Sha512Update (HashCtx, Data, DataSize); Status = Sha512Final (HashCtx, HashValue); } _Exit: if (HashCtx != NULL) { FreePool (HashCtx); } return Status; }
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; }