result_t crypto_base::pbkdf2(int32_t algo, Buffer_base* password, Buffer_base* salt, int32_t iterations, int32_t size, obj_ptr<Buffer_base>& retVal) { if (algo < hash_base::_MD2 || algo > hash_base::_RIPEMD160) return CHECK_ERROR(CALL_E_INVALIDARG); qstring str_pass; qstring str_salt; qstring str_key; password->toString(str_pass); salt->toString(str_salt); str_key.resize(size); mbedtls_md_context_t ctx; mbedtls_md_setup(&ctx, mbedtls_md_info_from_type((mbedtls_md_type_t)algo), 1); mbedtls_pkcs5_pbkdf2_hmac(&ctx, (const unsigned char *)str_pass.c_str(), str_pass.length(), (const unsigned char *)str_salt.c_str(), str_salt.length(), iterations, size, (unsigned char *)&str_key[0]); mbedtls_md_free(&ctx); retVal = new Buffer(str_key); return 0; }
SHACTX sha1_init(void) { SHACTX ctx = NULL; int rc; const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); if (md_info == NULL) { return NULL; } ctx = malloc(sizeof(mbedtls_md_context_t)); if (ctx == NULL) { return NULL; } mbedtls_md_init(ctx); rc = mbedtls_md_setup(ctx, md_info, 0); if (rc != 0) { SAFE_FREE(ctx); return NULL; } rc = mbedtls_md_starts(ctx); if (rc != 0) { SAFE_FREE(ctx); return NULL; } return ctx; }
BOOL winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md) { #if defined(WITH_OPENSSL) EVP_MD_CTX* mdctx = (EVP_MD_CTX*) ctx; const EVP_MD* evp = winpr_openssl_get_evp_md(md); if (!mdctx || !evp) return FALSE; if (EVP_DigestInit_ex(mdctx, evp, NULL) != 1) return FALSE; #elif defined(WITH_MBEDTLS) mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx; mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md); const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type); if (!md_info) return FALSE; if (mdctx->md_info != md_info) { mbedtls_md_free(mdctx); /* can be called at any time after mbedtls_md_init */ if (mbedtls_md_setup(mdctx, md_info, 0) != 0) return FALSE; } if (mbedtls_md_starts(mdctx) != 0) return FALSE; #endif return TRUE; }
EVPCTX evp_init(int nid) { EVPCTX ctx = NULL; int rc; mbedtls_md_type_t algo = nid_to_md_algo(nid); const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(algo); if (md_info == NULL) { return NULL; } ctx = malloc(sizeof(mbedtls_md_context_t)); if (ctx == NULL) { return NULL; } mbedtls_md_init(ctx); rc = mbedtls_md_setup(ctx, md_info, 0); if (rc != 0) { SAFE_FREE(ctx); return NULL; } rc = mbedtls_md_starts(ctx); if (rc != 0) { SAFE_FREE(ctx); return NULL; } return ctx; }
int winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, int md, const BYTE* key, size_t keylen) { #if defined(WITH_OPENSSL) const EVP_MD* evp = winpr_openssl_get_evp_md(md); if (!evp) return -1; HMAC_CTX_init((HMAC_CTX*) ctx); #if (OPENSSL_VERSION_NUMBER < 0x10000000L) HMAC_Init_ex((HMAC_CTX*) ctx, key, keylen, evp, NULL); #else if (HMAC_Init_ex((HMAC_CTX*) ctx, key, keylen, evp, NULL) != 1) return -1; #endif #elif defined(WITH_MBEDTLS) const mbedtls_md_info_t* md_info; mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md); md_info = mbedtls_md_info_from_type(md_type); if (!md_info) return -1; mbedtls_md_init((mbedtls_md_context_t*) ctx); if (mbedtls_md_setup((mbedtls_md_context_t*) ctx, md_info, 1) != 0) return -1; if (mbedtls_md_hmac_starts((mbedtls_md_context_t*) ctx, key, keylen) != 0) return -1; #endif return 0; }
int winpr_Digest_Init(WINPR_DIGEST_CTX* ctx, int md) { #if defined(WITH_OPENSSL) const EVP_MD* evp = winpr_openssl_get_evp_md(md); if (!evp) return -1; EVP_MD_CTX_init((EVP_MD_CTX*) ctx); if (EVP_DigestInit_ex((EVP_MD_CTX*) ctx, evp, NULL) != 1) return -1; #elif defined(WITH_MBEDTLS) const mbedtls_md_info_t* md_info; mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md); md_info = mbedtls_md_info_from_type(md_type); if (!md_info) return -1; mbedtls_md_init((mbedtls_md_context_t*) ctx); if (mbedtls_md_setup((mbedtls_md_context_t*) ctx, md_info, 0) != 0) return -1; if (mbedtls_md_starts((mbedtls_md_context_t*) ctx) != 0) return -1; #endif return 0; }
Digest::Digest(mbedtls_md_type_t algo, const char *key, int32_t sz) { m_bMac = true; m_iAlgo = algo; mbedtls_md_init(&m_ctx); mbedtls_md_setup(&m_ctx, mbedtls_md_info_from_type(algo), 1); mbedtls_md_hmac_starts(&m_ctx, (unsigned char *)key, sz); }
// ESP32 SHA256 void SHA256(uint8_t *dest, const uint8_t *data, size_t dataLength) { mbedtls_md_context_t ctx; mbedtls_md_init(&ctx); mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 0); mbedtls_md_starts(&ctx); mbedtls_md_update(&ctx, (const unsigned char *)data, dataLength); mbedtls_md_finish(&ctx, dest); }
void md_ctx_init(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *kt) { ASSERT(NULL != ctx && NULL != kt); mbedtls_md_init(ctx); ASSERT(0 == mbedtls_md_setup(ctx, kt, 0)); ASSERT(0 == mbedtls_md_starts(ctx)); }
Digest::Digest(mbedtls_md_type_t algo) { m_bMac = false; m_iAlgo = algo; mbedtls_md_init(&m_ctx); mbedtls_md_setup(&m_ctx, mbedtls_md_info_from_type(algo), 0); mbedtls_md_starts(&m_ctx); }
/*JSON{ "type" : "staticmethod", "class" : "crypto", "name" : "PBKDF2", "generate" : "jswrap_crypto_PBKDF2", "params" : [ ["passphrase","JsVar","Passphrase"], ["salt","JsVar","Salt for turning passphrase into a key"], ["options","JsVar","Object of Options, `{ keySize: 8 (in 32 bit words), iterations: 10, hasher: 'SHA1'/'SHA224'/'SHA256'/'SHA384'/'SHA512' }`"] ], "return" : ["JsVar","Returns an ArrayBuffer"], "return_object" : "ArrayBuffer", "ifdef" : "USE_TLS" } Password-Based Key Derivation Function 2 algorithm, using SHA512 */ JsVar *jswrap_crypto_PBKDF2(JsVar *passphrase, JsVar *salt, JsVar *options) { int iterations = 1; int keySize = 128/32; mbedtls_md_type_t hasher = MBEDTLS_MD_SHA1; if (jsvIsObject(options)) { keySize = jsvGetIntegerAndUnLock(jsvObjectGetChild(options, "keySize", 0)); if (keySize<=0) keySize=128/32; iterations = jsvGetIntegerAndUnLock(jsvObjectGetChild(options, "iterations", 0)); if (iterations<1) iterations = 1; JsVar *hashVar = jsvObjectGetChild(options, "hasher", 0); if (!jsvIsUndefined(hashVar)) hasher = jswrap_crypto_getHasher(hashVar); jsvUnLock(hashVar); } else if (!jsvIsUndefined(options)) jsError("Options should be an object or undefined, got %t", options); if (hasher == MBEDTLS_MD_NONE) return 0; // already shown an error JSV_GET_AS_CHAR_ARRAY(passPtr, passLen, passphrase); if (!passPtr) return 0; JSV_GET_AS_CHAR_ARRAY(saltPtr, saltLen, salt); if (!saltPtr) return 0; int err; mbedtls_md_context_t ctx; mbedtls_md_init( &ctx ); err = mbedtls_md_setup( &ctx, mbedtls_md_info_from_type( hasher ), 1 ); assert(err==0); char *keyPtr = 0; JsVar *keyArr = jsvNewArrayBufferWithPtr((unsigned)keySize*4, &keyPtr); if (!keyPtr) { jsError("Not enough memory for result"); return 0; } err = mbedtls_pkcs5_pbkdf2_hmac( &ctx, (unsigned char*)passPtr, passLen, (unsigned char*)saltPtr, saltLen, (unsigned)iterations, (unsigned)keySize*4, (unsigned char*)keyPtr ); mbedtls_md_free( &ctx ); if (!err) { return keyArr; } else { jswrap_crypto_error(err); jsvUnLock(keyArr); return 0; } }
/* * HMAC_DRBG initialisation (10.1.2.3 + 9.1) */ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, const mbedtls_md_info_t * md_info, int (*f_entropy)(void *, unsigned char *, size_t), void *p_entropy, const unsigned char *custom, size_t len ) { int ret; size_t entropy_len, md_size; if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 ) return( ret ); md_size = mbedtls_md_get_size( md_info ); /* * Set initial working state. * Use the V memory location, which is currently all 0, to initialize the * MD context with an all-zero key. Then set V to its initial value. */ if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 ) return( ret ); memset( ctx->V, 0x01, md_size ); ctx->f_entropy = f_entropy; ctx->p_entropy = p_entropy; ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL; /* * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by * each hash function, then according to SP800-90A rev1 10.1 table 2, * min_entropy_len (in bits) is security_strength. * * (This also matches the sizes used in the NIST test vectors.) */ entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */ md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */ 32; /* better (256+) -> 256 bits */ /* * For initialisation, use more entropy to emulate a nonce * (Again, matches test vectors.) */ ctx->entropy_len = entropy_len * 3 / 2; if( ( ret = mbedtls_hmac_drbg_reseed( ctx, custom, len ) ) != 0 ) return( ret ); ctx->entropy_len = entropy_len; return( 0 ); }
void hmac_ctx_init(mbedtls_md_context_t *ctx, const uint8_t *key, int key_len, const mbedtls_md_info_t *kt) { ASSERT(NULL != kt && NULL != ctx); mbedtls_md_init(ctx); ASSERT(0 == mbedtls_md_setup(ctx, kt, 1)); ASSERT(0 == mbedtls_md_hmac_starts(ctx, key, key_len)); /* make sure we used a big enough key */ ASSERT(mbedtls_md_get_size(kt) <= key_len); }
int mbedtls_pkcs5_self_test( int verbose ) { mbedtls_md_context_t sha1_ctx; const mbedtls_md_info_t *info_sha1; int ret, i; unsigned char key[64]; mbedtls_md_init( &sha1_ctx ); info_sha1 = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); if( info_sha1 == NULL ) { ret = 1; goto exit; } if( ( ret = mbedtls_md_setup( &sha1_ctx, info_sha1, 1 ) ) != 0 ) { ret = 1; goto exit; } for( i = 0; i < MAX_TESTS; i++ ) { if( verbose != 0 ) mbedtls_printf( " PBKDF2 (SHA1) #%d: ", i ); ret = mbedtls_pkcs5_pbkdf2_hmac( &sha1_ctx, password[i], plen[i], salt[i], slen[i], it_cnt[i], key_len[i], key ); if( ret != 0 || memcmp( result_key[i], key, key_len[i] ) != 0 ) { if( verbose != 0 ) mbedtls_printf( "failed\n" ); ret = 1; goto exit; } if( verbose != 0 ) mbedtls_printf( "passed\n" ); } if( verbose != 0 ) mbedtls_printf( "\n" ); exit: mbedtls_md_free( &sha1_ctx ); return( ret ); }
ssh_mac_ctx ssh_mac_ctx_init(enum ssh_mac_e type) { ssh_mac_ctx ctx = malloc(sizeof (struct ssh_mac_ctx_struct)); const mbedtls_md_info_t *md_info; int rc; if (ctx == NULL) { return NULL; } ctx->mac_type=type; switch(type) { case SSH_MAC_SHA1: md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); break; case SSH_MAC_SHA256: md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); break; case SSH_MAC_SHA384: md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA384); break; case SSH_MAC_SHA512: md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); break; default: goto error; } if (md_info == NULL) { goto error; } mbedtls_md_init(&ctx->ctx); rc = mbedtls_md_setup(&ctx->ctx, md_info, 0); if (rc != 0) { goto error; } rc = mbedtls_md_starts(&ctx->ctx); if (rc != 0) { goto error; } return ctx; error: SAFE_FREE(ctx); return NULL; }
HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) { HMACCTX ctx = NULL; const mbedtls_md_info_t *md_info = NULL; int rc; ctx = malloc(sizeof(mbedtls_md_context_t)); if (ctx == NULL) { return NULL; } switch (type) { case SSH_HMAC_SHA1: md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); break; case SSH_HMAC_SHA256: md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); break; case SSH_HMAC_SHA512: md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); break; default: goto error; } mbedtls_md_init(ctx); if (md_info == NULL) { goto error; } rc = mbedtls_md_setup(ctx, md_info, 1); if (rc != 0) { goto error; } rc = mbedtls_md_hmac_starts(ctx, key, len); if (rc != 0) { goto error; } return ctx; error: mbedtls_md_free(ctx); SAFE_FREE(ctx); return NULL; }
bool HMAC_Validate(COSE_MacMessage * pcose, int HSize, int TSize, const byte * pbKey, size_t cbKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr) { mbedtls_md_context_t contx; const char* md_name; const struct mbedtls_md_info_t * info; byte * rgbOut = NULL; unsigned int cbOut; bool f = false; unsigned int i; #ifdef USE_CBOR_CONTEXT cn_cbor_context * context = &pcose->m_message.m_allocContext; #endif switch (HSize) { case 256: md_name = "SHA256"; break; case 384: md_name = "SHA384"; break; case 512: md_name = "SHA512"; break; default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); break; } mbedtls_md_init(&contx); info = mbedtls_md_info_from_string (md_name); mbedtls_md_setup( &contx, info, 1 ); cbOut = mbedtls_md_get_size(info); rgbOut = COSE_CALLOC(cbOut, 1, context); CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY); CHECK_CONDITION(!(mbedtls_md_hmac_starts (&contx, (char*)pbKey, cbKey)), COSE_ERR_CRYPTO_FAIL); CHECK_CONDITION(!(mbedtls_md_hmac_update (&contx, pbAuthData, cbAuthData)), COSE_ERR_CRYPTO_FAIL); CHECK_CONDITION(!(mbedtls_md_hmac_finish (&contx, rgbOut)), COSE_ERR_CRYPTO_FAIL); cn_cbor * cn = _COSE_arrayget_int(&pcose->m_message, INDEX_MAC_TAG); CHECK_CONDITION(cn != NULL, COSE_ERR_CBOR); if (cn->length > (int) cbOut) return false; for (i = 0; i < (unsigned int) TSize/8; i++) f |= (cn->v.bytes[i] != rgbOut[i]); mbedtls_md_free(&contx); return !f; errorReturn: COSE_FREE(rgbOut, context); mbedtls_md_free(&contx); return false; }
bool gtkhash_hash_lib_mbedtls_is_supported(const enum hash_func_e id) { mbedtls_md_type_t type; if (!gtkhash_hash_lib_mbedtls_set_type(id, &type)) return false; struct hash_lib_mbedtls_s data; mbedtls_md_init(&data.ctx); const mbedtls_md_info_t *info = mbedtls_md_info_from_type(type); if (mbedtls_md_setup(&data.ctx, info, 0) != 0) { mbedtls_md_free(&data.ctx); return false; } mbedtls_md_free(&data.ctx); return true; }
bool HMAC_Create(COSE_MacMessage * pcose, int HSize, int TSize, const byte * pbKey, size_t cbKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr) { byte * rgbOut = NULL; // unsigned int cbOut; mbedtls_md_context_t contx; const char* md_name; const struct mbedtls_md_info_t * info; #ifdef USE_CBOR_CONTEXT cn_cbor_context * context = &pcose->m_message.m_allocContext; #endif switch (HSize) { case 256: md_name = "SHA256"; break; case 384: md_name = "SHA384"; break; case 512: md_name = "SHA512"; break; default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); break; } if (0) { errorReturn: COSE_FREE(rgbOut, context); mbedtls_md_free(&contx); return false; } mbedtls_md_init(&contx); info = mbedtls_md_info_from_string (md_name); mbedtls_md_setup( &contx, info, 1 ); rgbOut = COSE_CALLOC(mbedtls_md_get_size(info), 1, context); CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY); CHECK_CONDITION(!(mbedtls_md_hmac_starts (&contx, (char*)pbKey, cbKey)), COSE_ERR_CRYPTO_FAIL); CHECK_CONDITION(!(mbedtls_md_hmac_update (&contx, pbAuthData, cbAuthData)), COSE_ERR_CRYPTO_FAIL); CHECK_CONDITION(!(mbedtls_md_hmac_finish (&contx, rgbOut)), COSE_ERR_CRYPTO_FAIL); CHECK_CONDITION(_COSE_array_replace(&pcose->m_message, cn_cbor_data_create(rgbOut, TSize / 8, CBOR_CONTEXT_PARAM_COMMA NULL), INDEX_MAC_TAG, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_CBOR); mbedtls_md_free(&contx); return true; }
/* * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA) */ int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx, const mbedtls_md_info_t * md_info, const unsigned char *data, size_t data_len ) { int ret; if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 ) return( ret ); /* * Set initial working state. * Use the V memory location, which is currently all 0, to initialize the * MD context with an all-zero key. Then set V to its initial value. */ mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, mbedtls_md_get_size( md_info ) ); memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) ); mbedtls_hmac_drbg_update( ctx, data, data_len ); return( 0 ); }
BOOL winpr_HMAC_Init(WINPR_HMAC_CTX* ctx, WINPR_MD_TYPE md, const BYTE* key, size_t keylen) { #if defined(WITH_OPENSSL) HMAC_CTX* hmac = (HMAC_CTX*) ctx; const EVP_MD* evp = winpr_openssl_get_evp_md(md); if (!evp || !hmac) return FALSE; #if (OPENSSL_VERSION_NUMBER < 0x10000000L) HMAC_Init_ex(hmac, key, keylen, evp, NULL); /* no return value on OpenSSL 0.9.x */ return TRUE; #else if (HMAC_Init_ex(hmac, key, keylen, evp, NULL) == 1) return TRUE; #endif #elif defined(WITH_MBEDTLS) mbedtls_md_context_t* hmac = (mbedtls_md_context_t*) ctx; mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md); const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type); if (!md_info || !hmac) return FALSE; if (hmac->md_info != md_info) { mbedtls_md_free(hmac); /* can be called at any time after mbedtls_md_init */ if (mbedtls_md_setup(hmac, md_info, 1) != 0) return FALSE; } if (mbedtls_md_hmac_starts(hmac, key, keylen) == 0) return TRUE; #endif return FALSE; }
// Usage example: // char* hash_in = "Uniform input text"; // uint8_t* hash_out = (uint8_t*) alloca(64); // if (0 == wrapped_hash((uint8_t*) hash_in, strlen(hash_in), hash_out, 32, Hashes::MBEDTLS_MD_SHA256)) { // printf("Hash value: "); // for (uint8_t i = 0; i < 32; i++) printf("0x%02x ", *(hash_out + i)); // printf("\n"); // } // else { // printf("Failed to hash.\n"); // } int8_t __attribute__((weak)) wrapped_hash(uint8_t* in, size_t in_len, uint8_t* out, Hashes h) { int8_t return_value = -1; const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type((mbedtls_md_type_t)h); if (NULL != md_info) { mbedtls_md_context_t ctx; mbedtls_md_init(&ctx); switch (mbedtls_md_setup(&ctx, md_info, 0)) { case 0: if (0 == mbedtls_md_starts(&ctx)) { // Start feeding data... if (0 == mbedtls_md_update(&ctx, in, in_len)) { if (0 == mbedtls_md_finish(&ctx, out)) { return_value = 0; } else { Kernel::log("hash(): Failed during finish.\n"); } } else { Kernel::log("hash(): Failed during digest.\n"); } } else { Kernel::log("hash(): Bad input data.\n"); } break; case MBEDTLS_ERR_MD_BAD_INPUT_DATA: Kernel::log("hash(): Bad parameters.\n"); break; case MBEDTLS_ERR_MD_ALLOC_FAILED: Kernel::log("hash(): Allocation failure.\n"); break; default: break; } mbedtls_md_free(&ctx); } return return_value; }
BOOL winpr_Digest_Init_Internal(WINPR_DIGEST_CTX* ctx, WINPR_MD_TYPE md) { mbedtls_md_context_t* mdctx = (mbedtls_md_context_t*) ctx; mbedtls_md_type_t md_type = winpr_mbedtls_get_md_type(md); const mbedtls_md_info_t* md_info = mbedtls_md_info_from_type(md_type); if (!md_info) return FALSE; if (mdctx->md_info != md_info) { mbedtls_md_free(mdctx); /* can be called at any time after mbedtls_md_init */ if (mbedtls_md_setup(mdctx, md_info, 0) != 0) return FALSE; } if (mbedtls_md_starts(mdctx) != 0) return FALSE; return TRUE; }
int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output ) { int ret; FILE *f; size_t n; mbedtls_md_context_t ctx; unsigned char buf[1024]; if( md_info == NULL ) return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); if( ( f = fopen( path, "rb" ) ) == NULL ) return( MBEDTLS_ERR_MD_FILE_IO_ERROR ); mbedtls_md_init( &ctx ); if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 ) goto cleanup; md_info->starts_func( ctx.md_ctx ); while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) md_info->update_func( ctx.md_ctx, buf, n ); if( ferror( f ) != 0 ) { ret = MBEDTLS_ERR_MD_FILE_IO_ERROR; goto cleanup; } md_info->finish_func( ctx.md_ctx, output ); cleanup: fclose( f ); mbedtls_md_free( &ctx ); return( ret ); }
int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen, const unsigned char *input, size_t ilen, unsigned char *output ) { mbedtls_md_context_t ctx; int ret; if( md_info == NULL ) return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); mbedtls_md_init( &ctx ); if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 ) return( ret ); mbedtls_md_hmac_starts( &ctx, key, keylen ); mbedtls_md_hmac_update( &ctx, input, ilen ); mbedtls_md_hmac_finish( &ctx, output ); mbedtls_md_free( &ctx ); return( 0 ); }
/* * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function */ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, const unsigned char *label, size_t label_len, size_t ilen, const unsigned char *input, unsigned char *output ) { size_t olen; int ret; unsigned char *p = output; unsigned int hlen; const mbedtls_md_info_t *md_info; mbedtls_md_context_t md_ctx; if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); if( f_rng == NULL ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id ); if( md_info == NULL ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); olen = ctx->len; hlen = mbedtls_md_get_size( md_info ); if( olen < ilen + 2 * hlen + 2 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); memset( output, 0, olen ); *p++ = 0; // Generate a random octet string seed // if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 ) return( MBEDTLS_ERR_RSA_RNG_FAILED + ret ); p += hlen; // Construct DB // mbedtls_md( md_info, label, label_len, p ); p += hlen; p += olen - 2 * hlen - 2 - ilen; *p++ = 1; memcpy( p, input, ilen ); mbedtls_md_init( &md_ctx ); mbedtls_md_setup( &md_ctx, md_info, 0 ); // maskedDB: Apply dbMask to DB // mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen, &md_ctx ); // maskedSeed: Apply seedMask to seed // mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1, &md_ctx ); mbedtls_md_free( &md_ctx ); return( ( mode == MBEDTLS_RSA_PUBLIC ) ? mbedtls_rsa_public( ctx, output, output ) : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) ); }
int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode, const unsigned char *pwd, size_t pwdlen, const unsigned char *data, size_t datalen, unsigned char *output ) { int ret, iterations = 0, keylen = 0; unsigned char *p, *end; mbedtls_asn1_buf kdf_alg_oid, enc_scheme_oid, kdf_alg_params, enc_scheme_params; mbedtls_asn1_buf salt; mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1; unsigned char key[32], iv[32]; size_t olen = 0; const mbedtls_md_info_t *md_info; const mbedtls_cipher_info_t *cipher_info; mbedtls_md_context_t md_ctx; mbedtls_cipher_type_t cipher_alg; mbedtls_cipher_context_t cipher_ctx; p = pbe_params->p; end = p + pbe_params->len; /* * PBES2-params ::= SEQUENCE { * keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}}, * encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} * } */ if( pbe_params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); if( ( ret = mbedtls_asn1_get_alg( &p, end, &kdf_alg_oid, &kdf_alg_params ) ) != 0 ) return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); // Only PBKDF2 supported at the moment // if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS5_PBKDF2, &kdf_alg_oid ) != 0 ) return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); if( ( ret = pkcs5_parse_pbkdf2_params( &kdf_alg_params, &salt, &iterations, &keylen, &md_type ) ) != 0 ) { return( ret ); } md_info = mbedtls_md_info_from_type( md_type ); if( md_info == NULL ) return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); if( ( ret = mbedtls_asn1_get_alg( &p, end, &enc_scheme_oid, &enc_scheme_params ) ) != 0 ) { return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); } if( mbedtls_oid_get_cipher_alg( &enc_scheme_oid, &cipher_alg ) != 0 ) return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); cipher_info = mbedtls_cipher_info_from_type( cipher_alg ); if( cipher_info == NULL ) return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); /* * The value of keylen from pkcs5_parse_pbkdf2_params() is ignored * since it is optional and we don't know if it was set or not */ keylen = cipher_info->key_bitlen / 8; if( enc_scheme_params.tag != MBEDTLS_ASN1_OCTET_STRING || enc_scheme_params.len != cipher_info->iv_size ) { return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT ); } mbedtls_md_init( &md_ctx ); mbedtls_cipher_init( &cipher_ctx ); memcpy( iv, enc_scheme_params.p, enc_scheme_params.len ); if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) goto exit; if( ( ret = mbedtls_pkcs5_pbkdf2_hmac( &md_ctx, pwd, pwdlen, salt.p, salt.len, iterations, keylen, key ) ) != 0 ) { goto exit; } if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 ) goto exit; if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 ) goto exit; if( ( ret = mbedtls_cipher_crypt( &cipher_ctx, iv, enc_scheme_params.len, data, datalen, output, &olen ) ) != 0 ) ret = MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH; exit: mbedtls_md_free( &md_ctx ); mbedtls_cipher_free( &cipher_ctx ); return( ret ); }
int bytes_to_key(const cipher_kt_t *cipher, const digest_type_t *md, const uint8_t *pass, uint8_t *key, uint8_t *iv) { size_t datal; datal = strlen((const char *)pass); #if defined(USE_CRYPTO_OPENSSL) return EVP_BytesToKey(cipher, md, NULL, pass, datal, 1, key, iv); #elif defined(USE_CRYPTO_POLARSSL) md_context_t c; unsigned char md_buf[MAX_MD_SIZE]; int niv; int nkey; int addmd; unsigned int mds; unsigned int i; int rv; nkey = cipher_key_size(cipher); niv = cipher_iv_size(cipher); rv = nkey; if (pass == NULL) { return nkey; } memset(&c, 0, sizeof(md_context_t)); if (md_init_ctx(&c, md)) { return 0; } addmd = 0; mds = md_get_size(md); for (;;) { int error; do { error = 1; if (md_starts(&c)) { break; } if (addmd) { if (md_update(&c, &(md_buf[0]), mds)) { break; } } else { addmd = 1; } if (md_update(&c, pass, datal)) { break; } if (md_finish(&c, &(md_buf[0]))) { break; } error = 0; } while (0); if (error) { md_free_ctx(&c); memset(md_buf, 0, MAX_MD_SIZE); return 0; } i = 0; if (nkey) { for (;;) { if (nkey == 0) { break; } if (i == mds) { break; } if (key != NULL) { *(key++) = md_buf[i]; } nkey--; i++; } } if (niv && (i != mds)) { for (;;) { if (niv == 0) { break; } if (i == mds) { break; } if (iv != NULL) { *(iv++) = md_buf[i]; } niv--; i++; } } if ((nkey == 0) && (niv == 0)) { break; } } md_free_ctx(&c); memset(md_buf, 0, MAX_MD_SIZE); return rv; #elif defined(USE_CRYPTO_MBEDTLS) /* * * Generic message digest context. * * typedef struct { * Information about the associated message digest * const mbedtls_md_info_t *md_info; * * Digest-specific context * void *md_ctx; * * HMAC part of the context * void *hmac_ctx; * } mbedtls_md_context_t; // mbedtls 2.0.0 * * typedef struct { * Information about the associated message digest * const md_info_t *md_info; * * Digest-specific context * void *md_ctx; * } md_context_t; //polarssl 1.3 * */ // NOTE: different struct body, initialize new param hmac 0 to disable HMAC mbedtls_md_context_t c; unsigned char md_buf[MAX_MD_SIZE]; int niv; int nkey; int addmd; unsigned int mds; unsigned int i; int rv; nkey = cipher_key_size(cipher); niv = cipher_iv_size(cipher); rv = nkey; if (pass == NULL) { return nkey; } memset(&c, 0, sizeof(mbedtls_md_context_t)); // XXX: md_init_ctx superseded by mbedtls_md_setup() in 2.0.0 // new param hmac 0 to save some memory if HMAC will not be used, // non-zero is HMAC is going to be used with this context. if (mbedtls_md_setup(&c, md, 1)) { return 0; } addmd = 0; mds = mbedtls_md_get_size(md); for (;;) { int error; do { error = 1; if (mbedtls_md_starts(&c)) { break; } if (addmd) { if (mbedtls_md_update(&c, &(md_buf[0]), mds)) { break; } } else { addmd = 1; } if (mbedtls_md_update(&c, pass, datal)) { break; } if (mbedtls_md_finish(&c, &(md_buf[0]))) { break; } error = 0; } while (0); if (error) { mbedtls_md_free(&c); // md_free_ctx deprecated, Use mbedtls_md_free() instead memset(md_buf, 0, MAX_MD_SIZE); return 0; } i = 0; if (nkey) { for (;;) { if (nkey == 0) { break; } if (i == mds) { break; } if (key != NULL) { *(key++) = md_buf[i]; } nkey--; i++; } } if (niv && (i != mds)) { for (;;) { if (niv == 0) { break; } if (i == mds) { break; } if (iv != NULL) { *(iv++) = md_buf[i]; } niv--; i++; } } if ((nkey == 0) && (niv == 0)) { break; } } mbedtls_md_free(&c); // NOTE: md_free_ctx deprecated, Use mbedtls_md_free() instead memset(md_buf, 0, MAX_MD_SIZE); return rv; #endif }
/* * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function */ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, const unsigned char *label, size_t label_len, size_t *olen, const unsigned char *input, unsigned char *output, size_t output_max_len ) { int ret; size_t ilen, i, pad_len; unsigned char *p, bad, pad_done; unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; unsigned char lhash[MBEDTLS_MD_MAX_SIZE]; unsigned int hlen; const mbedtls_md_info_t *md_info; mbedtls_md_context_t md_ctx; /* * Parameters sanity checks */ if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); ilen = ctx->len; if( ilen < 16 || ilen > sizeof( buf ) ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id ); if( md_info == NULL ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); /* * RSA operation */ ret = ( mode == MBEDTLS_RSA_PUBLIC ) ? mbedtls_rsa_public( ctx, input, buf ) : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf ); if( ret != 0 ) return( ret ); /* * Unmask data and generate lHash */ hlen = mbedtls_md_get_size( md_info ); mbedtls_md_init( &md_ctx ); mbedtls_md_setup( &md_ctx, md_info, 0 ); /* Generate lHash */ mbedtls_md( md_info, label, label_len, lhash ); /* seed: Apply seedMask to maskedSeed */ mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1, &md_ctx ); /* DB: Apply dbMask to maskedDB */ mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen, &md_ctx ); mbedtls_md_free( &md_ctx ); /* * Check contents, in "constant-time" */ p = buf; bad = 0; bad |= *p++; /* First byte must be 0 */ p += hlen; /* Skip seed */ /* Check lHash */ for( i = 0; i < hlen; i++ ) bad |= lhash[i] ^ *p++; /* Get zero-padding len, but always read till end of buffer * (minus one, for the 01 byte) */ pad_len = 0; pad_done = 0; for( i = 0; i < ilen - 2 * hlen - 2; i++ ) { pad_done |= p[i]; pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1; } p += pad_len; bad |= *p++ ^ 0x01; /* * The only information "leaked" is whether the padding was correct or not * (eg, no data is copied if it was not correct). This meets the * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between * the different error conditions. */ if( bad != 0 ) return( MBEDTLS_ERR_RSA_INVALID_PADDING ); if( ilen - ( p - buf ) > output_max_len ) return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); *olen = ilen - (p - buf); memcpy( output, p, *olen ); return( 0 ); }
int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) { return mbedtls_md_setup( ctx, md_info, 1 ); }