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; }
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; }
WINPR_HMAC_CTX* winpr_HMAC_New(void) { WINPR_HMAC_CTX* ctx = NULL; #if defined(WITH_OPENSSL) HMAC_CTX* hmac = NULL; #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) if (!(hmac = (HMAC_CTX*) calloc(1, sizeof(HMAC_CTX)))) return NULL; HMAC_CTX_init(hmac); #else if (!(hmac = HMAC_CTX_new())) return NULL; #endif ctx = (WINPR_HMAC_CTX*) hmac; #elif defined(WITH_MBEDTLS) mbedtls_md_context_t* hmac; if (!(hmac = (mbedtls_md_context_t*) calloc(1, sizeof(mbedtls_md_context_t)))) return NULL; mbedtls_md_init(hmac); ctx = (WINPR_HMAC_CTX*) hmac; #endif return ctx; }
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; }
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); }
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); }
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)); }
/*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; } }
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; }
// 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; }
WINPR_DIGEST_CTX* winpr_Digest_New(void) { WINPR_DIGEST_CTX* ctx = NULL; #if defined(WITH_OPENSSL) EVP_MD_CTX* mdctx; #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) mdctx = EVP_MD_CTX_create(); #else mdctx = EVP_MD_CTX_new(); #endif ctx = (WINPR_DIGEST_CTX*) mdctx; #elif defined(WITH_MBEDTLS) mbedtls_md_context_t* mdctx; mdctx = (mbedtls_md_context_t*) calloc(1, sizeof(mbedtls_md_context_t)); if (mdctx) mbedtls_md_init(mdctx); ctx = (WINPR_DIGEST_CTX*) mdctx; #endif return ctx; }
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 ); }
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 ); }
HmacImpl(const uint8_t* secret, size_t secretLen) { mbedtls_md_init(&m_ctx); mbedtls_md_setup(&m_ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1); mbedtls_md_hmac_starts(&m_ctx, secret, secretLen); }
/* * 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 ) ); }
int example(void) { printf( "\r\n\r\n" ); /* * Method 1: use all-in-one function of a specific SHA-xxx module */ unsigned char output1[32]; /* SHA-256 outputs 32 bytes */ /* 0 here means use the full SHA-256, not the SHA-224 variant */ mbedtls_sha256(hello_buffer, hello_len, output1, 0); print_hex("Method 1", output1, sizeof output1); /* * Method 2: use the streaming interface of a specific SHA-xxx module * This is useful if we get our input piecewise. */ unsigned char output2[32]; mbedtls_sha256_context ctx2; mbedtls_sha256_init(&ctx2); mbedtls_sha256_starts(&ctx2, 0); /* SHA-256, not 224 */ /* Simulating multiple fragments */ mbedtls_sha256_update(&ctx2, hello_buffer, 1); mbedtls_sha256_update(&ctx2, hello_buffer + 1, 1); mbedtls_sha256_update(&ctx2, hello_buffer + 2, hello_len - 2); mbedtls_sha256_finish(&ctx2, output2); print_hex("Method 2", output2, sizeof output2); /* Or you could re-use the context by doing mbedtls_sha256_starts() again */ mbedtls_sha256_free(&ctx2); /* * Method 3: use all-in-one function of the generice interface */ unsigned char output3[MBEDTLS_MD_MAX_SIZE]; /* Enough for any hash */ /* Can easily pick any hash you want, by identifier */ const mbedtls_md_info_t *md_info3 = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); if (md_info3 == NULL) { printf("SHA256 not available\r\n"); return 1; } int ret3 = mbedtls_md(md_info3, hello_buffer, hello_len, output3); if (ret3 != 0) { printf("md() returned -0x%04X\r\n", -ret3); return 1; } print_hex("Method 3", output3, mbedtls_md_get_size(md_info3)); /* * Method 4: streaming & generic interface */ unsigned char output4[MBEDTLS_MD_MAX_SIZE]; /* Enough for any hash */ const mbedtls_md_info_t *md_info4 = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); if (md_info4 == NULL) { printf("SHA256 not available\r\n"); return 1; } mbedtls_md_context_t ctx4; mbedtls_md_init(&ctx4); int ret4 = mbedtls_md_init_ctx(&ctx4, md_info4); if (ret4 != 0) { printf("md_init_ctx() returned -0x%04X\r\n", -ret4); return 1; } mbedtls_md_starts(&ctx4); /* Simulating multiple fragments */ mbedtls_md_update(&ctx4, hello_buffer, 1); mbedtls_md_update(&ctx4, hello_buffer + 1, 1); mbedtls_md_update(&ctx4, hello_buffer + 2, hello_len - 2); mbedtls_md_finish(&ctx4, output4); print_hex("Method 4", output4, mbedtls_md_get_size(md_info4)); /* Or you could re-use the context by doing mbedtls_md_starts() again */ mbedtls_md_free(&ctx4); printf("\r\nDONE\r\n"); return 0; }