tt_result_t tt_ecdsa_verify(IN tt_ecdsa_t *dsa, IN tt_u8_t *input, IN tt_u32_t len, IN tt_md_type_t md_type, IN tt_u8_t *sig, IN tt_u32_t sig_len) { mbedtls_ecdsa_context *ctx = &dsa->ctx; mbedtls_md_type_t t; const mbedtls_md_info_t *md_type_info; tt_u8_t hash[MBEDTLS_MD_MAX_SIZE]; tt_u32_t hashlen; int e; t = tt_g_md_type_map[md_type]; md_type_info = mbedtls_md_info_from_type(t); mbedtls_md(md_type_info, input, len, hash); hashlen = mbedtls_md_get_size(md_type_info); e = mbedtls_ecdsa_read_signature(ctx, hash, hashlen, sig, sig_len); if (e != 0) { tt_crypto_error("ecdsa verify failed"); return TT_FAIL; } return TT_SUCCESS; }
void show_available_digests() { const int *digests = mbedtls_md_list(); #ifndef ENABLE_SMALL printf("The following message digests are available for use with\n" PACKAGE_NAME ". A message digest is used in conjunction with\n" "the HMAC function, to authenticate received packets.\n" "You can specify a message digest as parameter to\n" "the --auth option.\n\n"); #endif while (*digests != 0) { const mbedtls_md_info_t *info = mbedtls_md_info_from_type(*digests); if (info) { printf("%s %d bit default key\n", mbedtls_md_get_name(info), mbedtls_md_get_size(info) * 8); } digests++; } printf("\n"); }
void hmac_final(HMACCTX c, unsigned char *hashmacbuf, unsigned int *len) { *len = mbedtls_md_get_size(c->md_info); mbedtls_md_hmac_finish(c, hashmacbuf); mbedtls_md_free(c); SAFE_FREE(c); }
void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen) { *mdlen = mbedtls_md_get_size(ctx->md_info); mbedtls_md_finish(ctx, md); mbedtls_md_free(ctx); SAFE_FREE(ctx); }
/* * HMAC_DRBG update, using optional additional data (10.1.2.2) */ void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx, const unsigned char *additional, size_t add_len ) { const mbedtls_md_info_t *info; size_t md_len; int /* unsigned char */ rounds; unsigned char sep[1]; unsigned char K[MBEDTLS_MD_MAX_SIZE]; int sep_value; info = ctx->md_ctx.md_info; md_len = mbedtls_md_get_size( info ); rounds = ( add_len != 0 && additional != NULL ) ? 2 : 1; /* rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1; */ for( sep_value = 0; sep_value < rounds; sep_value++ ) { sep[0] = sep_value; /* Step 1 or 4 */ mbedtls_md_hmac_reset( &ctx->md_ctx ); mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len ); mbedtls_md_hmac_update( &ctx->md_ctx, sep, 1 ); if( rounds == 2 ) mbedtls_md_hmac_update( &ctx->md_ctx, additional, add_len ); mbedtls_md_hmac_finish( &ctx->md_ctx, K ); /* Step 2 or 5 */ mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ); mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len ); mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ); } }
result_t Digest::get_size(int32_t &retVal) { if (m_iAlgo < 0) return CHECK_ERROR(CALL_E_INVALID_CALL); retVal = mbedtls_md_get_size(m_ctx.md_info); return 0; }
Hash(std::string hashstr) { std::transform(hashstr.begin(), hashstr.end(), hashstr.begin(), ::toupper); md = mbedtls_md_info_from_string(hashstr.c_str()); if (!md) throw Exception("Unknown hash: " + hashstr); buf.resize(mbedtls_md_get_size(md)); }
int hmac_ctx_size(const mbedtls_md_context_t *ctx) { if (NULL == ctx) { return 0; } return mbedtls_md_get_size(ctx->md_info); }
int md_kt_size(const mbedtls_md_info_t *kt) { if (NULL == kt) { return 0; } return mbedtls_md_get_size(kt); }
/* * HMAC_DRBG random function with optional additional data: * 10.1.2.5 (arabic) + 9.3 (Roman) */ int mbedtls_hmac_drbg_random_with_add( void *p_rng, unsigned char *output, size_t out_len, const unsigned char *additional, size_t add_len ) { int ret; mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng; size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info ); size_t left = out_len; unsigned char *out = output; /* II. Check request length */ if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST ) return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG ); /* III. Check input length */ if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT ) return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); /* 1. (aka VII and IX) Check reseed counter and PR */ if( ctx->f_entropy != NULL && /* For no-reseeding instances */ ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON || ctx->reseed_counter > ctx->reseed_interval ) ) { if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 ) return( ret ); add_len = 0; /* VII.4 */ } /* 2. Use additional data if any */ if( additional != NULL && add_len != 0 ) mbedtls_hmac_drbg_update( ctx, additional, add_len ); /* 3, 4, 5. Generate bytes */ while( left != 0 ) { size_t use_len = left > md_len ? md_len : left; mbedtls_md_hmac_reset( &ctx->md_ctx ); mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len ); mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ); memcpy( out, ctx->V, use_len ); out += use_len; left -= use_len; } /* 6. Update */ mbedtls_hmac_drbg_update( ctx, additional, add_len ); /* 7. Update reseed counter */ ctx->reseed_counter++; /* 8. Done */ return( 0 ); }
const mbedtls_md_info_t * md_kt_get(const char *digest) { const mbedtls_md_info_t *md = NULL; ASSERT(digest); md = mbedtls_md_info_from_string(digest); if (!md) { msg(M_FATAL, "Message hash algorithm '%s' not found", digest); } if (mbedtls_md_get_size(md) > MAX_HMAC_KEY_LENGTH) { msg(M_FATAL, "Message hash algorithm '%s' uses a default hash size (%d bytes) which is larger than " PACKAGE_NAME "'s current maximum hash size (%d bytes)", digest, mbedtls_md_get_size(md), MAX_HMAC_KEY_LENGTH); } return md; }
/* * 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 ); }
/* * 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 ); }
bool ECDSA_Verify(COSE * pSigner, int index, const cn_cbor * pKey, int cbitDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr) { mbedtls_ecp_keypair keypair; mbedtls_mpi r; mbedtls_mpi s; mbedtls_md_type_t mdType; const mbedtls_md_info_t *pmdInfo; byte rgbDigest[MBEDTLS_MD_MAX_SIZE]; cn_cbor * pSig; bool result = false; mbedtls_ecp_keypair_init(&keypair); mbedtls_mpi_init(&r); mbedtls_mpi_init(&s); if(!ECKey_From(pKey, &keypair, perr)) goto errorReturn; switch(cbitDigest) { case 256: mdType = MBEDTLS_MD_SHA256; break; case 384: mdType = MBEDTLS_MD_SHA384; break; case 512: mdType = MBEDTLS_MD_SHA512; break; default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); } pmdInfo = mbedtls_md_info_from_type(mdType); CHECK_CONDITION(pmdInfo != NULL, COSE_ERR_INVALID_PARAMETER); CHECK_CONDITION(mbedtls_md(pmdInfo, rgbToSign, cbToSign, rgbDigest) == 0, COSE_ERR_INVALID_PARAMETER); pSig = _COSE_arrayget_int(pSigner, index); CHECK_CONDITION((pSig != NULL) && (pSig->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER); CHECK_CONDITION(mbedtls_mpi_read_binary( &r, pSig->v.bytes, pSig->length / 2 ) == 0, COSE_ERR_OUT_OF_MEMORY); CHECK_CONDITION(mbedtls_mpi_read_binary( &s, pSig->v.bytes + pSig->length / 2, pSig->length / 2 ) == 0, COSE_ERR_OUT_OF_MEMORY); CHECK_CONDITION(mbedtls_ecdsa_verify(&keypair.grp, rgbDigest, mbedtls_md_get_size(pmdInfo), &keypair.Q, &r, &s) == 0, COSE_ERR_CRYPTO_FAIL); result = true; errorReturn: mbedtls_mpi_free(&r); mbedtls_mpi_free(&s); mbedtls_ecp_keypair_free(&keypair); return result; }
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); }
void evp(int nid, unsigned char *digest, int len, unsigned char *hash, unsigned int *hlen) { 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) { *hlen = mbedtls_md_get_size(md_info); mbedtls_md(md_info, digest, len, hash); } }
/* * Helper for mbedtls_pk_sign and mbedtls_pk_verify */ static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len ) { const mbedtls_md_info_t *md_info; if( *hash_len != 0 ) return( 0 ); if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL ) return( -1 ); *hash_len = mbedtls_md_get_size( md_info ); return( 0 ); }
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; }
/* * HMAC_DRBG update, using optional additional data (10.1.2.2) */ int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx, const unsigned char *additional, size_t add_len ) { size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info ); unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1; unsigned char sep[1]; unsigned char K[MBEDTLS_MD_MAX_SIZE]; int ret; for( sep[0] = 0; sep[0] < rounds; sep[0]++ ) { /* Step 1 or 4 */ if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 ) goto exit; if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len ) ) != 0 ) goto exit; if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, sep, 1 ) ) != 0 ) goto exit; if( rounds == 2 ) { if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, additional, add_len ) ) != 0 ) goto exit; } if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 ) goto exit; /* Step 2 or 5 */ if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 ) goto exit; if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len ) ) != 0 ) goto exit; if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 ) goto exit; } exit: mbedtls_platform_zeroize( K, sizeof( K ) ); return( ret ); }
static value dgst_make(value data, value alg){ const mbedtls_md_info_t *md; int r = -1; value out; val_check(data, string); val_check(alg, string); md = mbedtls_md_info_from_string(val_string(alg)); if( md == NULL ){ val_throw(alloc_string("Invalid hash algorithm")); return val_null; } out = alloc_empty_string( mbedtls_md_get_size(md) ); if( (r = mbedtls_md( md, (const unsigned char *)val_string(data), val_strlen(data), (unsigned char *)val_string(out) )) != 0 ) return ssl_error(r); return out; }
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; }
result_t Digest::digest(obj_ptr<Buffer_base> &retVal) { if (m_iAlgo < 0) return CHECK_ERROR(CALL_E_INVALID_CALL); std::string strBuf; strBuf.resize(mbedtls_md_get_size(m_ctx.md_info)); if (m_bMac) mbedtls_md_hmac_finish(&m_ctx, (unsigned char *) &strBuf[0]); else mbedtls_md_finish(&m_ctx, (unsigned char *) &strBuf[0]); m_iAlgo = -1; mbedtls_md_hmac_reset(&m_ctx); retVal = new Buffer(strBuf); return 0; }
tt_result_t tt_ecdsa_sign(IN tt_ecdsa_t *dsa, IN tt_u8_t *input, IN tt_u32_t len, IN tt_md_type_t md_type, IN tt_md_type_t sig_md, OUT tt_u8_t *sig, IN OUT tt_u32_t *sig_len) { mbedtls_ecdsa_context *ctx = &dsa->ctx; mbedtls_md_type_t t; const mbedtls_md_info_t *md_type_info; tt_u8_t hash[MBEDTLS_MD_MAX_SIZE]; tt_u32_t hashlen; size_t slen = *sig_len; int e; t = tt_g_md_type_map[md_type]; md_type_info = mbedtls_md_info_from_type(t); mbedtls_md(md_type_info, input, len, hash); hashlen = mbedtls_md_get_size(md_type_info); e = mbedtls_ecdsa_write_signature(ctx, tt_g_md_type_map[sig_md], hash, hashlen, sig, &slen, tt_ctr_drbg, tt_current_ctr_drbg()); if (e != 0) { tt_crypto_error("ecdsa sign failed"); return TT_FAIL; } *sig_len = (tt_u32_t)slen; return TT_SUCCESS; }
/** * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer. * * \param dst buffer to mask * \param dlen length of destination buffer * \param src source of the mask generation * \param slen length of the source buffer * \param md_ctx message digest context to use */ static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src, size_t slen, mbedtls_md_context_t *md_ctx ) { unsigned char mask[MBEDTLS_MD_MAX_SIZE]; unsigned char counter[4]; unsigned char *p; unsigned int hlen; size_t i, use_len; memset( mask, 0, MBEDTLS_MD_MAX_SIZE ); memset( counter, 0, 4 ); hlen = mbedtls_md_get_size( md_ctx->md_info ); // Generate and apply dbMask // p = dst; while( dlen > 0 ) { use_len = hlen; if( dlen < hlen ) use_len = dlen; mbedtls_md_starts( md_ctx ); mbedtls_md_update( md_ctx, src, slen ); mbedtls_md_update( md_ctx, counter, 4 ); mbedtls_md_finish( md_ctx, mask ); for( i = 0; i < use_len; ++i ) *p++ ^= mask[i]; counter[3]++; dlen -= use_len; } }
/* * HMAC_DRBG update, using optional additional data (10.1.2.2) */ void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx, const unsigned char *additional, size_t add_len ) { size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info ); unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1; unsigned char sep[1]; unsigned char K[MBEDTLS_MD_MAX_SIZE]; for( sep[0] = 0; sep[0] < rounds; sep[0]++ ) { /* Step 1 or 4 */ mbedtls_md_hmac_reset( &ctx->md_ctx ); mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len ); mbedtls_md_hmac_update( &ctx->md_ctx, sep, 1 ); if( rounds == 2 ) mbedtls_md_hmac_update( &ctx->md_ctx, additional, add_len ); mbedtls_md_hmac_finish( &ctx->md_ctx, K ); /* Step 2 or 5 */ mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ); mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len ); mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ); } }
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 ); }
/* * 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 ) ); }
void test_md_get_size() { mbedtls_md_info_t info; unsigned char ret; ret = mbedtls_md_get_size(&info); }
size_t hash::length(hash_t type) { const auto* cinfot = native_type(type); return mbedtls_md_get_size(cinfot); }