diff options
author | Adam Langley <agl@google.com> | 2015-05-11 17:20:37 -0700 |
---|---|---|
committer | Kenny Root <kroot@google.com> | 2015-05-12 23:06:14 +0000 |
commit | e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5 (patch) | |
tree | 6e43e34595ecf887c26c32b86d8ab097fe8cac64 /src/crypto/evp | |
parent | b3106a0cc1493bbe0505c0ec0ce3da4ca90a29ae (diff) | |
download | external_boringssl-e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5.zip external_boringssl-e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5.tar.gz external_boringssl-e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5.tar.bz2 |
external/boringssl: bump revision.
This change bumps the BoringSSL revision to the current tip-of-tree.
Change-Id: I91d5bf467e16e8d86cb19a4de873985f524e5faa
Diffstat (limited to 'src/crypto/evp')
-rw-r--r-- | src/crypto/evp/CMakeLists.txt | 14 | ||||
-rw-r--r-- | src/crypto/evp/asn1.c | 2 | ||||
-rw-r--r-- | src/crypto/evp/digestsign.c | 35 | ||||
-rw-r--r-- | src/crypto/evp/evp.c | 42 | ||||
-rw-r--r-- | src/crypto/evp/evp_ctx.c | 41 | ||||
-rw-r--r-- | src/crypto/evp/evp_error.c | 131 | ||||
-rw-r--r-- | src/crypto/evp/evp_extra_test.cc (renamed from src/crypto/evp/evp_test.c) | 524 | ||||
-rw-r--r-- | src/crypto/evp/evp_test.cc | 262 | ||||
-rw-r--r-- | src/crypto/evp/evp_tests.txt | 174 | ||||
-rw-r--r-- | src/crypto/evp/internal.h | 43 | ||||
-rw-r--r-- | src/crypto/evp/p_dsa_asn1.c | 569 | ||||
-rw-r--r-- | src/crypto/evp/p_ec.c | 10 | ||||
-rw-r--r-- | src/crypto/evp/p_ec_asn1.c | 65 | ||||
-rw-r--r-- | src/crypto/evp/p_hmac.c | 3 | ||||
-rw-r--r-- | src/crypto/evp/p_rsa.c | 65 | ||||
-rw-r--r-- | src/crypto/evp/p_rsa_asn1.c | 42 | ||||
-rw-r--r-- | src/crypto/evp/pbkdf_test.cc | 179 | ||||
-rw-r--r-- | src/crypto/evp/sign.c | 10 |
18 files changed, 1629 insertions, 582 deletions
diff --git a/src/crypto/evp/CMakeLists.txt b/src/crypto/evp/CMakeLists.txt index 9854a18..6db9752 100644 --- a/src/crypto/evp/CMakeLists.txt +++ b/src/crypto/evp/CMakeLists.txt @@ -10,7 +10,7 @@ add_library( digestsign.c evp.c evp_ctx.c - evp_error.c + p_dsa_asn1.c p_ec.c p_ec_asn1.c p_hmac.c @@ -23,16 +23,24 @@ add_library( add_executable( + evp_extra_test + + evp_extra_test.cc +) + +add_executable( evp_test - evp_test.c + evp_test.cc + $<TARGET_OBJECTS:test_support> ) add_executable( pbkdf_test - pbkdf_test.c + pbkdf_test.cc ) +target_link_libraries(evp_extra_test crypto) target_link_libraries(evp_test crypto) target_link_libraries(pbkdf_test crypto) diff --git a/src/crypto/evp/asn1.c b/src/crypto/evp/asn1.c index 27ae017..3df9f52 100644 --- a/src/crypto/evp/asn1.c +++ b/src/crypto/evp/asn1.c @@ -105,7 +105,7 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp, return ret; err: - if (ret != NULL && (out == NULL || *out != ret)) { + if (out == NULL || *out != ret) { EVP_PKEY_free(ret); } return NULL; diff --git a/src/crypto/evp/digestsign.c b/src/crypto/evp/digestsign.c index c86b805..c163d40 100644 --- a/src/crypto/evp/digestsign.c +++ b/src/crypto/evp/digestsign.c @@ -65,9 +65,8 @@ /* md_begin_digset is a callback from the |EVP_MD_CTX| code that is called when * a new digest is begun. */ static int md_begin_digest(EVP_MD_CTX *ctx) { - int r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG, - EVP_PKEY_CTRL_DIGESTINIT, 0, ctx); - return r > 0 || r == -2; + return EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_DIGESTINIT, 0, ctx); } static const struct evp_md_pctx_ops md_pctx_ops = { @@ -98,24 +97,24 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, if (is_verify) { if (ctx->pctx->pmeth->verifyctx_init) { - if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <= 0) { + if (!ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx)) { return 0; } ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX; - } else if (EVP_PKEY_verify_init(ctx->pctx) <= 0) { + } else if (!EVP_PKEY_verify_init(ctx->pctx)) { return 0; } } else { if (ctx->pctx->pmeth->signctx_init) { - if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0) { + if (!ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx)) { return 0; } ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX; - } else if (EVP_PKEY_sign_init(ctx->pctx) <= 0) { + } else if (!EVP_PKEY_sign_init(ctx->pctx)) { return 0; } } - if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0) { + if (!EVP_PKEY_CTX_set_signature_md(ctx->pctx, type)) { return 0; } if (pctx) { @@ -163,12 +162,12 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, uint8_t *out_sig, r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx, out_sig, out_sig_len, &tmp_ctx); } else { r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen); + if (r) { + r = EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, md, mdlen); + } } EVP_MD_CTX_cleanup(&tmp_ctx); - if (has_signctx || !r) { - return r; - } - return EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, md, mdlen); + return r; } else { if (has_signctx) { return ctx->pctx->pmeth->signctx(ctx->pctx, out_sig, out_sig_len, ctx); @@ -185,21 +184,21 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, uint8_t md[EVP_MAX_MD_SIZE]; int r; unsigned int mdlen; - const int has_verifyctx = ctx->pctx->pmeth->verifyctx != NULL; EVP_MD_CTX_init(&tmp_ctx); if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) { return 0; } - if (has_verifyctx) { + if (ctx->pctx->pmeth->verifyctx) { r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx, sig, sig_len, &tmp_ctx); } else { r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen); + if (r) { + r = EVP_PKEY_verify(ctx->pctx, sig, sig_len, md, mdlen); + } } EVP_MD_CTX_cleanup(&tmp_ctx); - if (has_verifyctx || !r) { - return r; - } - return EVP_PKEY_verify(ctx->pctx, sig, sig_len, md, mdlen); + + return r; } diff --git a/src/crypto/evp/evp.c b/src/crypto/evp/evp.c index 8a1d513..58fd9a9 100644 --- a/src/crypto/evp/evp.c +++ b/src/crypto/evp/evp.c @@ -67,10 +67,12 @@ #include <openssl/mem.h> #include <openssl/obj.h> #include <openssl/rsa.h> +#include <openssl/thread.h> #include "internal.h" +extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth; extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth; extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth; extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth; @@ -109,15 +111,14 @@ void EVP_PKEY_free(EVP_PKEY *pkey) { } free_it(pkey); - if (pkey->attributes) { - /* TODO(fork): layering: X509_ATTRIBUTE_free is an X.509 function. In - * practice this path isn't called but should be removed in the future. */ - /*sk_X509_ATTRIBUTE_pop_free(pkey->attributes, X509_ATTRIBUTE_free);*/ - assert(0); - } OPENSSL_free(pkey); } +EVP_PKEY *EVP_PKEY_up_ref(EVP_PKEY *pkey) { + CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); + return pkey; +} + int EVP_PKEY_is_opaque(const EVP_PKEY *pkey) { if (pkey->ameth && pkey->ameth->pkey_opaque) { return pkey->ameth->pkey_opaque(pkey); @@ -142,8 +143,9 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { /* Compare parameters if the algorithm has them */ if (a->ameth->param_cmp) { ret = a->ameth->param_cmp(a, b); - if (ret <= 0) + if (ret <= 0) { return ret; + } } if (a->ameth->pub_cmp) { @@ -154,11 +156,6 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { return -2; } -EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey) { - CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); - return pkey; -} - int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { if (to->type != from->type) { OPENSSL_PUT_ERROR(EVP, EVP_PKEY_copy_parameters, EVP_R_DIFFERENT_KEY_TYPES); @@ -213,6 +210,8 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pengine, int nid) { return &hmac_asn1_meth; case EVP_PKEY_EC: return &ec_asn1_meth; + case EVP_PKEY_DSA: + return &dsa_asn1_meth; default: return NULL; } @@ -236,18 +235,19 @@ EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, const uint8_t *mac_key, return NULL; } - if (EVP_PKEY_keygen_init(mac_ctx) <= 0 || - EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN, - EVP_PKEY_CTRL_SET_MAC_KEY, mac_key_len, - (uint8_t *)mac_key) <= 0 || - EVP_PKEY_keygen(mac_ctx, &ret) <= 0) { + if (!EVP_PKEY_keygen_init(mac_ctx) || + !EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_SET_MAC_KEY, mac_key_len, + (uint8_t *)mac_key) || + !EVP_PKEY_keygen(mac_ctx, &ret)) { ret = NULL; goto merr; } merr: - if (mac_ctx) + if (mac_ctx) { EVP_PKEY_CTX_free(mac_ctx); + } return ret; } @@ -323,7 +323,7 @@ int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) { } int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key) { - return EVP_PKEY_assign(pkey, EVP_PKEY_EC, key); + return EVP_PKEY_assign(pkey, EVP_PKEY_DH, key); } DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) { @@ -435,6 +435,10 @@ int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { 0, (void *)out_md); } +EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey) { + return EVP_PKEY_up_ref(pkey); +} + void OpenSSL_add_all_algorithms(void) {} void EVP_cleanup(void) {} diff --git a/src/crypto/evp/evp_ctx.c b/src/crypto/evp/evp_ctx.c index a383725..9f42274 100644 --- a/src/crypto/evp/evp_ctx.c +++ b/src/crypto/evp/evp_ctx.c @@ -120,14 +120,12 @@ static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) { ret->operation = EVP_PKEY_OP_UNDEFINED; if (pkey) { - ret->pkey = EVP_PKEY_dup(pkey); + ret->pkey = EVP_PKEY_up_ref(pkey); } if (pmeth->init) { if (pmeth->init(ret) <= 0) { - if (pkey) { - EVP_PKEY_free(ret->pkey); - } + EVP_PKEY_free(ret->pkey); OPENSSL_free(ret); return NULL; } @@ -151,12 +149,8 @@ void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) { if (ctx->pmeth && ctx->pmeth->cleanup) { ctx->pmeth->cleanup(ctx); } - if (ctx->pkey) { - EVP_PKEY_free(ctx->pkey); - } - if (ctx->peerkey) { - EVP_PKEY_free(ctx->peerkey); - } + EVP_PKEY_free(ctx->pkey); + EVP_PKEY_free(ctx->peerkey); OPENSSL_free(ctx); } @@ -179,14 +173,14 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx) { rctx->operation = pctx->operation; if (pctx->pkey) { - rctx->pkey = EVP_PKEY_dup(pctx->pkey); + rctx->pkey = EVP_PKEY_up_ref(pctx->pkey); if (rctx->pkey == NULL) { goto err; } } if (pctx->peerkey) { - rctx->peerkey = EVP_PKEY_dup(pctx->peerkey); + rctx->peerkey = EVP_PKEY_up_ref(pctx->peerkey); if (rctx->peerkey == NULL) { goto err; } @@ -212,32 +206,25 @@ void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx) { return ctx->app_data; } int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2) { - int ret; if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) { OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_ctrl, EVP_R_COMMAND_NOT_SUPPORTED); - return -2; + return 0; } if (keytype != -1 && ctx->pmeth->pkey_id != keytype) { - return -1; + return 0; } if (ctx->operation == EVP_PKEY_OP_UNDEFINED) { OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_ctrl, EVP_R_NO_OPERATION_SET); - return -1; + return 0; } if (optype != -1 && !(ctx->operation & optype)) { OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_ctrl, EVP_R_INVALID_OPERATION); - return -1; - } - - ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2); - - if (ret == -2) { - OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_ctrl, EVP_R_COMMAND_NOT_SUPPORTED); + return 0; } - return ret; + return ctx->pmeth->ctrl(ctx, cmd, p1, p2); } int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) { @@ -434,9 +421,7 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) { return 0; } - if (ctx->peerkey) { - EVP_PKEY_free(ctx->peerkey); - } + EVP_PKEY_free(ctx->peerkey); ctx->peerkey = peer; ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer); @@ -446,7 +431,7 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) { return 0; } - EVP_PKEY_dup(peer); + EVP_PKEY_up_ref(peer); return 1; } diff --git a/src/crypto/evp/evp_error.c b/src/crypto/evp/evp_error.c deleted file mode 100644 index b0d311e..0000000 --- a/src/crypto/evp/evp_error.c +++ /dev/null @@ -1,131 +0,0 @@ -/* Copyright (c) 2014, Google Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -#include <openssl/err.h> - -#include <openssl/evp.h> - -const ERR_STRING_DATA EVP_error_string_data[] = { - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DigestSignAlgorithm, 0), "EVP_DigestSignAlgorithm"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DigestVerifyInitFromAlgorithm, 0), "EVP_DigestVerifyInitFromAlgorithm"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_ctrl, 0), "EVP_PKEY_CTX_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_dup, 0), "EVP_PKEY_CTX_dup"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_copy_parameters, 0), "EVP_PKEY_copy_parameters"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_decrypt, 0), "EVP_PKEY_decrypt"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_decrypt_init, 0), "EVP_PKEY_decrypt_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_derive, 0), "EVP_PKEY_derive"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_derive_init, 0), "EVP_PKEY_derive_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_derive_set_peer, 0), "EVP_PKEY_derive_set_peer"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_encrypt, 0), "EVP_PKEY_encrypt"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_encrypt_init, 0), "EVP_PKEY_encrypt_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_get1_DH, 0), "EVP_PKEY_get1_DH"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_get1_DSA, 0), "EVP_PKEY_get1_DSA"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_get1_EC_KEY, 0), "EVP_PKEY_get1_EC_KEY"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_get1_RSA, 0), "EVP_PKEY_get1_RSA"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_keygen, 0), "EVP_PKEY_keygen"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_keygen_init, 0), "EVP_PKEY_keygen_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_new, 0), "EVP_PKEY_new"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_set_type, 0), "EVP_PKEY_set_type"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_sign, 0), "EVP_PKEY_sign"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_sign_init, 0), "EVP_PKEY_sign_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_verify, 0), "EVP_PKEY_verify"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_verify_init, 0), "EVP_PKEY_verify_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_check_padding_md, 0), "check_padding_md"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_d2i_AutoPrivateKey, 0), "d2i_AutoPrivateKey"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_d2i_PrivateKey, 0), "d2i_PrivateKey"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_do_EC_KEY_print, 0), "do_EC_KEY_print"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_do_rsa_print, 0), "do_rsa_print"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_do_sigver_init, 0), "do_sigver_init"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_eckey_param2type, 0), "eckey_param2type"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_eckey_param_decode, 0), "eckey_param_decode"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_eckey_priv_decode, 0), "eckey_priv_decode"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_eckey_priv_encode, 0), "eckey_priv_encode"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_eckey_pub_decode, 0), "eckey_pub_decode"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_eckey_pub_encode, 0), "eckey_pub_encode"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_eckey_type2param, 0), "eckey_type2param"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_evp_pkey_ctx_new, 0), "evp_pkey_ctx_new"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_hmac_signctx, 0), "hmac_signctx"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_i2d_PublicKey, 0), "i2d_PublicKey"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_old_ec_priv_decode, 0), "old_ec_priv_decode"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_old_rsa_priv_decode, 0), "old_rsa_priv_decode"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_pkey_ec_ctrl, 0), "pkey_ec_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_pkey_ec_derive, 0), "pkey_ec_derive"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_pkey_ec_keygen, 0), "pkey_ec_keygen"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_pkey_ec_paramgen, 0), "pkey_ec_paramgen"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_pkey_ec_sign, 0), "pkey_ec_sign"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_pkey_rsa_ctrl, 0), "pkey_rsa_ctrl"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_pkey_rsa_decrypt, 0), "pkey_rsa_decrypt"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_pkey_rsa_encrypt, 0), "pkey_rsa_encrypt"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_pkey_rsa_sign, 0), "pkey_rsa_sign"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_rsa_algor_to_md, 0), "rsa_algor_to_md"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_rsa_digest_verify_init_from_algorithm, 0), "rsa_digest_verify_init_from_algorithm"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_rsa_item_verify, 0), "rsa_item_verify"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_rsa_mgf1_to_md, 0), "rsa_mgf1_to_md"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_rsa_priv_decode, 0), "rsa_priv_decode"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_rsa_priv_encode, 0), "rsa_priv_encode"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_rsa_pss_to_ctx, 0), "rsa_pss_to_ctx"}, - {ERR_PACK(ERR_LIB_EVP, EVP_F_rsa_pub_decode, 0), "rsa_pub_decode"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BUFFER_TOO_SMALL), "BUFFER_TOO_SMALL"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_COMMAND_NOT_SUPPORTED), "COMMAND_NOT_SUPPORTED"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CONTEXT_NOT_INITIALISED), "CONTEXT_NOT_INITIALISED"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DECODE_ERROR), "DECODE_ERROR"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIFFERENT_KEY_TYPES), "DIFFERENT_KEY_TYPES"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIFFERENT_PARAMETERS), "DIFFERENT_PARAMETERS"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED), "DIGEST_AND_KEY_TYPE_NOT_SUPPORTED"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIGEST_DOES_NOT_MATCH), "DIGEST_DOES_NOT_MATCH"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_AN_DSA_KEY), "EXPECTING_AN_DSA_KEY"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_AN_EC_KEY_KEY), "EXPECTING_AN_EC_KEY_KEY"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_AN_RSA_KEY), "EXPECTING_AN_RSA_KEY"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_DH_KEY), "EXPECTING_A_DH_KEY"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_DSA_KEY), "EXPECTING_A_DSA_KEY"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPLICIT_EC_PARAMETERS_NOT_SUPPORTED), "EXPLICIT_EC_PARAMETERS_NOT_SUPPORTED"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE), "ILLEGAL_OR_UNSUPPORTED_PADDING_MODE"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_CURVE), "INVALID_CURVE"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_DIGEST_LENGTH), "INVALID_DIGEST_LENGTH"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_DIGEST_TYPE), "INVALID_DIGEST_TYPE"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEYBITS), "INVALID_KEYBITS"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_MGF1_MD), "INVALID_MGF1_MD"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_OPERATION), "INVALID_OPERATION"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_PADDING_MODE), "INVALID_PADDING_MODE"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_PSS_PARAMETERS), "INVALID_PSS_PARAMETERS"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_PSS_SALTLEN), "INVALID_PSS_SALTLEN"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SALT_LENGTH), "INVALID_SALT_LENGTH"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_TRAILER), "INVALID_TRAILER"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KDF_PARAMETER_ERROR), "KDF_PARAMETER_ERROR"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEYS_NOT_SET), "KEYS_NOT_SET"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MISSING_PARAMETERS), "MISSING_PARAMETERS"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_DEFAULT_DIGEST), "NO_DEFAULT_DIGEST"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEY_SET), "NO_KEY_SET"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_MDC2_SUPPORT), "NO_MDC2_SUPPORT"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_NID_FOR_CURVE), "NO_NID_FOR_CURVE"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_OPERATION_SET), "NO_OPERATION_SET"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_PARAMETERS_SET), "NO_PARAMETERS_SET"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), "OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATON_NOT_INITIALIZED), "OPERATON_NOT_INITIALIZED"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PEER_KEY_ERROR), "PEER_KEY_ERROR"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_SHARED_INFO_ERROR), "SHARED_INFO_ERROR"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_DIGEST), "UNKNOWN_DIGEST"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_MASK_DIGEST), "UNKNOWN_MASK_DIGEST"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM), "UNKNOWN_MESSAGE_DIGEST_ALGORITHM"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE), "UNKNOWN_PUBLIC_KEY_TYPE"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_SIGNATURE_ALGORITHM), "UNKNOWN_SIGNATURE_ALGORITHM"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_ALGORITHM), "UNSUPPORTED_ALGORITHM"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_MASK_ALGORITHM), "UNSUPPORTED_MASK_ALGORITHM"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_MASK_PARAMETER), "UNSUPPORTED_MASK_PARAMETER"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE), "UNSUPPORTED_PUBLIC_KEY_TYPE"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_SIGNATURE_TYPE), "UNSUPPORTED_SIGNATURE_TYPE"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_WRONG_PUBLIC_KEY_TYPE), "WRONG_PUBLIC_KEY_TYPE"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_X931_UNSUPPORTED), "X931_UNSUPPORTED"}, - {0, NULL}, -}; diff --git a/src/crypto/evp/evp_test.c b/src/crypto/evp/evp_extra_test.cc index 3e74cd5..674547d 100644 --- a/src/crypto/evp/evp_test.c +++ b/src/crypto/evp/evp_extra_test.cc @@ -16,7 +16,8 @@ #include <stdio.h> #include <stdlib.h> -#include <openssl/bio.h> +#include <vector> + #include <openssl/bytestring.h> #include <openssl/crypto.h> #include <openssl/digest.h> @@ -25,9 +26,11 @@ #include <openssl/rsa.h> #include <openssl/x509.h> +#include "../test/scoped_types.h" + -/* kExampleRSAKeyDER is an RSA private key in ASN.1, DER format. Of course, you - * should never use this key anywhere but in an example. */ +// kExampleRSAKeyDER is an RSA private key in ASN.1, DER format. Of course, you +// should never use this key anywhere but in an example. static const uint8_t kExampleRSAKeyDER[] = { 0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xf8, 0xb8, 0x6c, 0x83, 0xb4, 0xbc, 0xd9, 0xa8, 0x57, 0xc0, 0xa5, 0xb4, 0x59, @@ -82,6 +85,81 @@ static const uint8_t kExampleRSAKeyDER[] = { 0x2d, 0x86, 0x9d, 0xa5, 0x20, 0x1b, 0xe5, 0xdf, }; +static const uint8_t kExampleDSAKeyDER[] = { + 0x30, 0x82, 0x03, 0x56, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, + 0x9e, 0x12, 0xfa, 0xb3, 0xde, 0x12, 0x21, 0x35, 0x01, 0xdd, 0x82, 0xaa, + 0x10, 0xca, 0x2d, 0x10, 0x1d, 0x2d, 0x4e, 0xbf, 0xef, 0x4d, 0x2a, 0x3f, + 0x8d, 0xaa, 0x0f, 0xe0, 0xce, 0xda, 0xd8, 0xd6, 0xaf, 0x85, 0x61, 0x6a, + 0xa2, 0xf3, 0x25, 0x2c, 0x0a, 0x2b, 0x5a, 0x6d, 0xb0, 0x9e, 0x6f, 0x14, + 0x90, 0x0e, 0x0d, 0xdb, 0x83, 0x11, 0x87, 0x6d, 0xd8, 0xf9, 0x66, 0x95, + 0x25, 0xf9, 0x9e, 0xd6, 0x59, 0x49, 0xe1, 0x84, 0xd5, 0x06, 0x47, 0x93, + 0x27, 0x11, 0x69, 0xa2, 0x28, 0x68, 0x0b, 0x95, 0xec, 0x12, 0xf5, 0x9a, + 0x8e, 0x20, 0xb2, 0x1f, 0x2b, 0x58, 0xeb, 0x2a, 0x20, 0x12, 0xd3, 0x5b, + 0xde, 0x2e, 0xe3, 0x51, 0x82, 0x2f, 0xe8, 0xf3, 0x2d, 0x0a, 0x33, 0x05, + 0x65, 0xdc, 0xce, 0x5c, 0x67, 0x2b, 0x72, 0x59, 0xc1, 0x4b, 0x24, 0x33, + 0xd0, 0xb5, 0xb2, 0xca, 0x2b, 0x2d, 0xb0, 0xab, 0x62, 0x6e, 0x8f, 0x13, + 0xf4, 0x7f, 0xe0, 0x34, 0x5d, 0x90, 0x4e, 0x72, 0x94, 0xbb, 0x03, 0x8e, + 0x9c, 0xe2, 0x1a, 0x9e, 0x58, 0x0b, 0x83, 0x35, 0x62, 0x78, 0x70, 0x6c, + 0xfe, 0x76, 0x84, 0x36, 0xc6, 0x9d, 0xe1, 0x49, 0xcc, 0xff, 0x98, 0xb4, + 0xaa, 0xb8, 0xcb, 0x4f, 0x63, 0x85, 0xc9, 0xf1, 0x02, 0xce, 0x59, 0x34, + 0x6e, 0xae, 0xef, 0x27, 0xe0, 0xad, 0x22, 0x2d, 0x53, 0xd6, 0xe8, 0x9c, + 0xc8, 0xcd, 0xe5, 0x77, 0x6d, 0xd0, 0x00, 0x57, 0xb0, 0x3f, 0x2d, 0x88, + 0xab, 0x3c, 0xed, 0xba, 0xfd, 0x7b, 0x58, 0x5f, 0x0b, 0x7f, 0x78, 0x35, + 0xe1, 0x7a, 0x37, 0x28, 0xbb, 0xf2, 0x5e, 0xa6, 0x25, 0x72, 0xf2, 0x45, + 0xdc, 0x11, 0x1f, 0x3c, 0xe3, 0x9c, 0xb6, 0xff, 0xac, 0xc3, 0x1b, 0x0a, + 0x27, 0x90, 0xe7, 0xbd, 0xe9, 0x02, 0x24, 0xea, 0x9b, 0x09, 0x31, 0x53, + 0x62, 0xaf, 0x3d, 0x2b, 0x02, 0x21, 0x00, 0xf3, 0x81, 0xdc, 0xf5, 0x3e, + 0xbf, 0x72, 0x4f, 0x8b, 0x2e, 0x5c, 0xa8, 0x2c, 0x01, 0x0f, 0xb4, 0xb5, + 0xed, 0xa9, 0x35, 0x8d, 0x0f, 0xd8, 0x8e, 0xd2, 0x78, 0x58, 0x94, 0x88, + 0xb5, 0x4f, 0xc3, 0x02, 0x82, 0x01, 0x00, 0x0c, 0x40, 0x2a, 0x72, 0x5d, + 0xcc, 0x3a, 0x62, 0xe0, 0x2b, 0xf4, 0xcf, 0x43, 0xcd, 0x17, 0xf4, 0xa4, + 0x93, 0x59, 0x12, 0x20, 0x22, 0x36, 0x69, 0xcf, 0x41, 0x93, 0xed, 0xab, + 0x42, 0x3a, 0xd0, 0x8d, 0xfb, 0x55, 0x2e, 0x30, 0x8a, 0x6a, 0x57, 0xa5, + 0xff, 0xbc, 0x7c, 0xd0, 0xfb, 0x20, 0x87, 0xf8, 0x1f, 0x8d, 0xf0, 0xcb, + 0x08, 0xab, 0x21, 0x33, 0x28, 0x7d, 0x2b, 0x69, 0x68, 0x71, 0x4a, 0x94, + 0xf6, 0x33, 0xc9, 0x40, 0x84, 0x5a, 0x48, 0xa3, 0xe1, 0x67, 0x08, 0xdd, + 0xe7, 0x61, 0xcc, 0x6a, 0x8e, 0xab, 0x2d, 0x84, 0xdb, 0x21, 0xb6, 0xea, + 0x5b, 0x07, 0x68, 0x14, 0x93, 0xcc, 0x9c, 0x31, 0xfb, 0xc3, 0x68, 0xb2, + 0x43, 0xf6, 0xdd, 0xf8, 0xc9, 0x32, 0xa8, 0xb4, 0x03, 0x8f, 0x44, 0xe7, + 0xb1, 0x5c, 0xa8, 0x76, 0x34, 0x4a, 0x14, 0x78, 0x59, 0xf2, 0xb4, 0x3b, + 0x39, 0x45, 0x86, 0x68, 0xad, 0x5e, 0x0a, 0x1a, 0x9a, 0x66, 0x95, 0x46, + 0xdd, 0x28, 0x12, 0xe3, 0xb3, 0x61, 0x7a, 0x0a, 0xef, 0x99, 0xd5, 0x8e, + 0x3b, 0xb4, 0xcc, 0x87, 0xfd, 0x94, 0x22, 0x5e, 0x01, 0xd2, 0xdc, 0xc4, + 0x69, 0xa7, 0x72, 0x68, 0x14, 0x6c, 0x51, 0x91, 0x8f, 0x18, 0xe8, 0xb4, + 0xd7, 0x0a, 0xa1, 0xf0, 0xc7, 0x62, 0x3b, 0xcc, 0x52, 0xcf, 0x37, 0x31, + 0xd3, 0x86, 0x41, 0xb2, 0xd2, 0x83, 0x0b, 0x7e, 0xec, 0xb2, 0xf0, 0x95, + 0x52, 0xff, 0x13, 0x7d, 0x04, 0x6e, 0x49, 0x4e, 0x7f, 0x33, 0xc3, 0x59, + 0x00, 0x02, 0xb1, 0x6d, 0x1b, 0x97, 0xd9, 0x36, 0xfd, 0xa2, 0x8f, 0x90, + 0xc3, 0xed, 0x3c, 0xa3, 0x53, 0x38, 0x16, 0x8a, 0xc1, 0x6f, 0x77, 0xc3, + 0xc5, 0x7a, 0xdc, 0x2e, 0x8f, 0x7c, 0x6c, 0x22, 0x56, 0xe4, 0x1a, 0x5f, + 0x65, 0x45, 0x05, 0x90, 0xdb, 0xb5, 0xbc, 0xf0, 0x6d, 0x66, 0x61, 0x02, + 0x82, 0x01, 0x00, 0x31, 0x97, 0x31, 0xa1, 0x4e, 0x38, 0x56, 0x88, 0xdb, + 0x94, 0x1d, 0xbf, 0x65, 0x5c, 0xda, 0x4b, 0xc2, 0x10, 0xde, 0x74, 0x20, + 0x03, 0xce, 0x13, 0x60, 0xf2, 0x25, 0x1d, 0x55, 0x7c, 0x5d, 0x94, 0x82, + 0x54, 0x08, 0x53, 0xdb, 0x85, 0x95, 0xbf, 0xdd, 0x5e, 0x50, 0xd5, 0x96, + 0xe0, 0x79, 0x51, 0x1b, 0xbf, 0x4d, 0x4e, 0xb9, 0x3a, 0xc5, 0xee, 0xc4, + 0x5e, 0x98, 0x75, 0x7b, 0xbe, 0xff, 0x30, 0xe6, 0xd0, 0x7b, 0xa6, 0xf1, + 0xbc, 0x29, 0xea, 0xdf, 0xec, 0xf3, 0x8b, 0xfa, 0x83, 0x11, 0x9f, 0x3f, + 0xf0, 0x5d, 0x06, 0x51, 0x32, 0xaa, 0x21, 0xfc, 0x26, 0x17, 0xe7, 0x50, + 0xc2, 0x16, 0xba, 0xfa, 0x54, 0xb7, 0x7e, 0x1d, 0x2c, 0xa6, 0xa3, 0x41, + 0x66, 0x33, 0x94, 0x83, 0xb9, 0xbf, 0xa0, 0x4f, 0xbd, 0xa6, 0xfd, 0x2c, + 0x81, 0x58, 0x35, 0x33, 0x39, 0xc0, 0x6d, 0x33, 0x40, 0x56, 0x64, 0x12, + 0x5a, 0xcd, 0x35, 0x53, 0x21, 0x78, 0x8f, 0x27, 0x24, 0x37, 0x66, 0x8a, + 0xdf, 0x5e, 0x5f, 0x63, 0xfc, 0x8b, 0x2d, 0xef, 0x57, 0xdb, 0x40, 0x25, + 0xd5, 0x17, 0x53, 0x0b, 0xe4, 0xa5, 0xae, 0x54, 0xbf, 0x46, 0x4f, 0xa6, + 0x79, 0xc3, 0x74, 0xfa, 0x1f, 0x85, 0x34, 0x64, 0x6d, 0xc5, 0x03, 0xeb, + 0x72, 0x98, 0x80, 0x7b, 0xc0, 0x8f, 0x35, 0x11, 0xa7, 0x09, 0xeb, 0x51, + 0xe0, 0xb0, 0xac, 0x92, 0x14, 0xf2, 0xad, 0x37, 0x95, 0x5a, 0xba, 0x8c, + 0xc4, 0xdb, 0xed, 0xc4, 0x4e, 0x8b, 0x8f, 0x84, 0x33, 0x64, 0xf8, 0x57, + 0x12, 0xd7, 0x08, 0x7e, 0x90, 0x66, 0xdf, 0x91, 0x50, 0x23, 0xf2, 0x73, + 0xc0, 0x6b, 0xb1, 0x15, 0xdd, 0x64, 0xd7, 0xc9, 0x75, 0x17, 0x73, 0x72, + 0xda, 0x33, 0xc4, 0x6f, 0xa5, 0x47, 0xa1, 0xcc, 0xd1, 0xc6, 0x62, 0xe5, + 0xca, 0xab, 0x5f, 0x2a, 0x8f, 0x6b, 0xcc, 0x02, 0x21, 0x00, 0xb0, 0xc7, + 0x68, 0x70, 0x27, 0x43, 0xbc, 0x51, 0x24, 0x29, 0x93, 0xa9, 0x71, 0xa5, + 0x28, 0x89, 0x79, 0x54, 0x44, 0xf7, 0xc6, 0x45, 0x22, 0x03, 0xd0, 0xce, + 0x84, 0xfe, 0x61, 0x17, 0xd4, 0x6e, +}; + static const uint8_t kMsg[] = {1, 2, 3, 4}; static const uint8_t kSignature[] = { @@ -98,8 +176,8 @@ static const uint8_t kSignature[] = { 0x55, 0xa7, 0xab, 0x45, 0x02, 0x97, 0x60, 0x42, }; -/* kExamplePSSCert is an example self-signed certificate, signed with - * kExampleRSAKeyDER using RSA-PSS with default hash functions. */ +// kExamplePSSCert is an example self-signed certificate, signed with +// kExampleRSAKeyDER using RSA-PSS with default hash functions. static const uint8_t kExamplePSSCert[] = { 0x30, 0x82, 0x02, 0x62, 0x30, 0x82, 0x01, 0xc6, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0x8d, 0xea, 0x53, 0x24, 0xfa, 0x48, 0x87, 0xf3, @@ -155,8 +233,8 @@ static const uint8_t kExamplePSSCert[] = { 0x8c, 0x16, }; -/* kExampleRSAKeyPKCS8 is kExampleRSAKeyDER encoded in a PKCS #8 - * PrivateKeyInfo. */ +// kExampleRSAKeyPKCS8 is kExampleRSAKeyDER encoded in a PKCS #8 +// PrivateKeyInfo. static const uint8_t kExampleRSAKeyPKCS8[] = { 0x30, 0x82, 0x02, 0x76, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, @@ -213,8 +291,8 @@ static const uint8_t kExampleRSAKeyPKCS8[] = { 0x08, 0xf1, 0x2d, 0x86, 0x9d, 0xa5, 0x20, 0x1b, 0xe5, 0xdf, }; -/* kExampleECKeyDER is a sample EC private key encoded as an ECPrivateKey - * structure. */ +// kExampleECKeyDER is a sample EC private key encoded as an ECPrivateKey +// structure. static const uint8_t kExampleECKeyDER[] = { 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x07, 0x0f, 0x08, 0x72, 0x7a, 0xd4, 0xa0, 0x4a, 0x9c, 0xdd, 0x59, 0xc9, 0x4d, 0x89, 0x68, 0x77, 0x08, @@ -229,8 +307,8 @@ static const uint8_t kExampleECKeyDER[] = { 0xc1, }; -/* kExampleBadECKeyDER is a sample EC private key encoded as an ECPrivateKey - * structure. The private key is equal to the order and will fail to import */ +// kExampleBadECKeyDER is a sample EC private key encoded as an ECPrivateKey +// structure. The private key is equal to the order and will fail to import. static const uint8_t kExampleBadECKeyDER[] = { 0x30, 0x66, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, @@ -243,237 +321,143 @@ static const uint8_t kExampleBadECKeyDER[] = { 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51 }; -static EVP_PKEY *load_example_rsa_key(void) { - EVP_PKEY *ret = NULL; +static ScopedEVP_PKEY LoadExampleRSAKey() { const uint8_t *derp = kExampleRSAKeyDER; - EVP_PKEY *pkey = NULL; - RSA *rsa = NULL; - - if (!d2i_RSAPrivateKey(&rsa, &derp, sizeof(kExampleRSAKeyDER))) { - return NULL; - } - - pkey = EVP_PKEY_new(); - if (pkey == NULL || !EVP_PKEY_set1_RSA(pkey, rsa)) { - goto out; - } - - ret = pkey; - pkey = NULL; - -out: - if (pkey) { - EVP_PKEY_free(pkey); + ScopedRSA rsa(d2i_RSAPrivateKey(nullptr, &derp, sizeof(kExampleRSAKeyDER))); + if (!rsa) { + return nullptr; } - if (rsa) { - RSA_free(rsa); + ScopedEVP_PKEY pkey(EVP_PKEY_new()); + if (!pkey || !EVP_PKEY_set1_RSA(pkey.get(), rsa.get())) { + return nullptr; } - - return ret; + return pkey; } -static int test_EVP_DigestSignInit(void) { - int ret = 0; - EVP_PKEY *pkey = NULL; - uint8_t *sig = NULL; - size_t sig_len = 0; - EVP_MD_CTX md_ctx, md_ctx_verify; - - EVP_MD_CTX_init(&md_ctx); - EVP_MD_CTX_init(&md_ctx_verify); - - pkey = load_example_rsa_key(); - if (pkey == NULL || - !EVP_DigestSignInit(&md_ctx, NULL, EVP_sha256(), NULL, pkey) || - !EVP_DigestSignUpdate(&md_ctx, kMsg, sizeof(kMsg))) { - goto out; +static bool TestEVP_DigestSignInit(void) { + ScopedEVP_PKEY pkey = LoadExampleRSAKey(); + ScopedEVP_MD_CTX md_ctx; + if (!pkey || + !EVP_DigestSignInit(md_ctx.get(), NULL, EVP_sha256(), NULL, pkey.get()) || + !EVP_DigestSignUpdate(md_ctx.get(), kMsg, sizeof(kMsg))) { + return false; } - /* Determine the size of the signature. */ - if (!EVP_DigestSignFinal(&md_ctx, NULL, &sig_len)) { - goto out; + // Determine the size of the signature. + size_t sig_len = 0; + if (!EVP_DigestSignFinal(md_ctx.get(), NULL, &sig_len)) { + return false; } - /* Sanity check for testing. */ - if (sig_len != EVP_PKEY_size(pkey)) { + // Sanity check for testing. + if (sig_len != (size_t)EVP_PKEY_size(pkey.get())) { fprintf(stderr, "sig_len mismatch\n"); - goto out; + return false; } - sig = malloc(sig_len); - if (sig == NULL || !EVP_DigestSignFinal(&md_ctx, sig, &sig_len)) { - goto out; + std::vector<uint8_t> sig; + sig.resize(sig_len); + if (!EVP_DigestSignFinal(md_ctx.get(), bssl::vector_data(&sig), &sig_len)) { + return false; } + sig.resize(sig_len); - /* Ensure that the signature round-trips. */ - if (!EVP_DigestVerifyInit(&md_ctx_verify, NULL, EVP_sha256(), NULL, pkey) || - !EVP_DigestVerifyUpdate(&md_ctx_verify, kMsg, sizeof(kMsg)) || - !EVP_DigestVerifyFinal(&md_ctx_verify, sig, sig_len)) { - goto out; + // Ensure that the signature round-trips. + md_ctx.Reset(); + if (!EVP_DigestVerifyInit(md_ctx.get(), NULL, EVP_sha256(), NULL, pkey.get()) || + !EVP_DigestVerifyUpdate(md_ctx.get(), kMsg, sizeof(kMsg)) || + !EVP_DigestVerifyFinal(md_ctx.get(), bssl::vector_data(&sig), sig_len)) { + return false; } - ret = 1; - -out: - if (!ret) { - BIO_print_errors_fp(stderr); - } - - EVP_MD_CTX_cleanup(&md_ctx); - EVP_MD_CTX_cleanup(&md_ctx_verify); - if (pkey) { - EVP_PKEY_free(pkey); - } - if (sig) { - free(sig); - } - - return ret; + return true; } -static int test_EVP_DigestVerifyInit(void) { - int ret = 0; - EVP_PKEY *pkey = NULL; - EVP_MD_CTX md_ctx; - - EVP_MD_CTX_init(&md_ctx); - - pkey = load_example_rsa_key(); - if (pkey == NULL || - !EVP_DigestVerifyInit(&md_ctx, NULL, EVP_sha256(), NULL, pkey) || - !EVP_DigestVerifyUpdate(&md_ctx, kMsg, sizeof(kMsg)) || - !EVP_DigestVerifyFinal(&md_ctx, kSignature, sizeof(kSignature))) { - goto out; - } - ret = 1; - -out: - if (!ret) { - BIO_print_errors_fp(stderr); - } - - EVP_MD_CTX_cleanup(&md_ctx); - if (pkey) { - EVP_PKEY_free(pkey); - } - - return ret; +static bool TestEVP_DigestVerifyInit(void) { + ScopedEVP_PKEY pkey = LoadExampleRSAKey(); + ScopedEVP_MD_CTX md_ctx; + if (!pkey || + !EVP_DigestVerifyInit(md_ctx.get(), NULL, EVP_sha256(), NULL, + pkey.get()) || + !EVP_DigestVerifyUpdate(md_ctx.get(), kMsg, sizeof(kMsg)) || + !EVP_DigestVerifyFinal(md_ctx.get(), kSignature, sizeof(kSignature))) { + return false; + } + return true; } -/* test_algorithm_roundtrip signs a message using an already-initialized - * |md_ctx|, sampling the AlgorithmIdentifier. It then uses |pkey| and the - * AlgorithmIdentifier to verify the signature. */ -static int test_algorithm_roundtrip(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) { - int ret = 0; - uint8_t *sig = NULL; - size_t sig_len = 0; - EVP_MD_CTX md_ctx_verify; - X509_ALGOR *algor = NULL; - - EVP_MD_CTX_init(&md_ctx_verify); - +// TestAlgorithmRoundtrip signs a message using an already-initialized +// |md_ctx|, sampling the AlgorithmIdentifier. It then uses |pkey| and the +// AlgorithmIdentifier to verify the signature. +static bool TestAlgorithmRoundtrip(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) { if (!EVP_DigestSignUpdate(md_ctx, kMsg, sizeof(kMsg))) { - goto out; + return false; } - /* Save the algorithm. */ - algor = X509_ALGOR_new(); - if (algor == NULL || !EVP_DigestSignAlgorithm(md_ctx, algor)) { - goto out; + // Save the algorithm. + ScopedX509_ALGOR algor(X509_ALGOR_new()); + if (!algor || !EVP_DigestSignAlgorithm(md_ctx, algor.get())) { + return false; } - /* Determine the size of the signature. */ + // Determine the size of the signature. + size_t sig_len = 0; if (!EVP_DigestSignFinal(md_ctx, NULL, &sig_len)) { - goto out; + return false; } - /* Sanity check for testing. */ - if (sig_len != EVP_PKEY_size(pkey)) { + // Sanity check for testing. + if (sig_len != (size_t)EVP_PKEY_size(pkey)) { fprintf(stderr, "sig_len mismatch\n"); - goto out; + return false; } - sig = malloc(sig_len); - if (sig == NULL || !EVP_DigestSignFinal(md_ctx, sig, &sig_len)) { - goto out; + std::vector<uint8_t> sig; + sig.resize(sig_len); + if (!EVP_DigestSignFinal(md_ctx, bssl::vector_data(&sig), &sig_len)) { + return false; } + sig.resize(sig_len); - /* Ensure that the signature round-trips. */ - if (!EVP_DigestVerifyInitFromAlgorithm(&md_ctx_verify, algor, pkey) || - !EVP_DigestVerifyUpdate(&md_ctx_verify, kMsg, sizeof(kMsg)) || - !EVP_DigestVerifyFinal(&md_ctx_verify, sig, sig_len)) { - goto out; + // Ensure that the signature round-trips. + ScopedEVP_MD_CTX md_ctx_verify; + if (!EVP_DigestVerifyInitFromAlgorithm(md_ctx_verify.get(), algor.get(), + pkey) || + !EVP_DigestVerifyUpdate(md_ctx_verify.get(), kMsg, sizeof(kMsg)) || + !EVP_DigestVerifyFinal(md_ctx_verify.get(), bssl::vector_data(&sig), + sig_len)) { + return false; } - ret = 1; - -out: - EVP_MD_CTX_cleanup(&md_ctx_verify); - if (sig) { - free(sig); - } - if (algor) { - X509_ALGOR_free(algor); - } - - return ret; + return true; } -static int test_EVP_DigestSignAlgorithm(void) { - int ret = 0; - EVP_PKEY *pkey = NULL; - EVP_MD_CTX md_ctx; - EVP_PKEY_CTX *pkey_ctx; - - EVP_MD_CTX_init(&md_ctx); - - pkey = load_example_rsa_key(); - if (pkey == NULL) { - goto out; - } +static bool TestEVP_DigestSignAlgorithm(void) { + ScopedEVP_PKEY pkey = LoadExampleRSAKey(); - /* Test a simple AlgorithmIdentifier. */ - if (!EVP_DigestSignInit(&md_ctx, &pkey_ctx, EVP_sha256(), NULL, pkey) || - !test_algorithm_roundtrip(&md_ctx, pkey)) { + // Test a simple AlgorithmIdentifier. + ScopedEVP_MD_CTX md_ctx; + if (!pkey || + !EVP_DigestSignInit(md_ctx.get(), NULL, EVP_sha256(), NULL, pkey.get()) || + !TestAlgorithmRoundtrip(md_ctx.get(), pkey.get())) { fprintf(stderr, "RSA with SHA-256 failed\n"); - goto out; + return false; } - EVP_MD_CTX_cleanup(&md_ctx); - EVP_MD_CTX_init(&md_ctx); - - /* Test RSA-PSS with custom parameters. */ - if (!EVP_DigestSignInit(&md_ctx, &pkey_ctx, EVP_sha256(), NULL, pkey) || - EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1 || - EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, EVP_sha512()) != 1 || - !test_algorithm_roundtrip(&md_ctx, pkey)) { + // Test RSA-PSS with custom parameters. + md_ctx.Reset(); + EVP_PKEY_CTX *pkey_ctx; + if (!EVP_DigestSignInit(md_ctx.get(), &pkey_ctx, EVP_sha256(), NULL, + pkey.get()) || + !EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) || + !EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, EVP_sha512()) || + !TestAlgorithmRoundtrip(md_ctx.get(), pkey.get())) { fprintf(stderr, "RSA-PSS failed\n"); - goto out; - } - - ret = 1; - -out: - if (!ret) { - BIO_print_errors_fp(stderr); + return false; } - EVP_MD_CTX_cleanup(&md_ctx); - if (pkey) { - EVP_PKEY_free(pkey); - } - - return ret; + return true; } -static int test_EVP_DigestVerifyInitFromAlgorithm(void) { - int ret = 0; +static bool TestEVP_DigestVerifyInitFromAlgorithm(void) { CBS cert, cert_body, tbs_cert, algorithm, signature; - uint8_t padding; - X509_ALGOR *algor = NULL; - const uint8_t *derp; - EVP_PKEY *pkey = NULL; - EVP_MD_CTX md_ctx; - - EVP_MD_CTX_init(&md_ctx); - CBS_init(&cert, kExamplePSSCert, sizeof(kExamplePSSCert)); if (!CBS_get_asn1(&cert, &cert_body, CBS_ASN1_SEQUENCE) || CBS_len(&cert) != 0 || @@ -482,155 +466,133 @@ static int test_EVP_DigestVerifyInitFromAlgorithm(void) { !CBS_get_asn1(&cert_body, &signature, CBS_ASN1_BITSTRING) || CBS_len(&cert_body) != 0) { fprintf(stderr, "Failed to parse certificate\n"); - goto out; + return false; } - /* Signatures are BIT STRINGs, but they have are multiple of 8 bytes, so the - leading phase byte is just a zero. */ + // Signatures are BIT STRINGs, but they have are multiple of 8 bytes, so the + // leading phase byte is just a zero. + uint8_t padding; if (!CBS_get_u8(&signature, &padding) || padding != 0) { fprintf(stderr, "Invalid signature padding\n"); - goto out; + return false; } - derp = CBS_data(&algorithm); - if (!d2i_X509_ALGOR(&algor, &derp, CBS_len(&algorithm)) || - derp != CBS_data(&algorithm) + CBS_len(&algorithm)) { + const uint8_t *derp = CBS_data(&algorithm); + ScopedX509_ALGOR algor(d2i_X509_ALGOR(NULL, &derp, CBS_len(&algorithm))); + if (!algor || derp != CBS_data(&algorithm) + CBS_len(&algorithm)) { fprintf(stderr, "Failed to parse algorithm\n"); + return false; } - pkey = load_example_rsa_key(); - if (pkey == NULL || - !EVP_DigestVerifyInitFromAlgorithm(&md_ctx, algor, pkey) || - !EVP_DigestVerifyUpdate(&md_ctx, CBS_data(&tbs_cert), + ScopedEVP_PKEY pkey = LoadExampleRSAKey(); + ScopedEVP_MD_CTX md_ctx; + if (!pkey || + !EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(), + pkey.get()) || + !EVP_DigestVerifyUpdate(md_ctx.get(), CBS_data(&tbs_cert), CBS_len(&tbs_cert)) || - !EVP_DigestVerifyFinal(&md_ctx, CBS_data(&signature), + !EVP_DigestVerifyFinal(md_ctx.get(), CBS_data(&signature), CBS_len(&signature))) { - goto out; - } - ret = 1; - -out: - if (!ret) { - BIO_print_errors_fp(stderr); + return false; } - - EVP_MD_CTX_cleanup(&md_ctx); - if (pkey) { - EVP_PKEY_free(pkey); - } - - return ret; + return true; } -static int test_d2i_AutoPrivateKey(const uint8_t *input, size_t input_len, +static bool Testd2i_AutoPrivateKey(const uint8_t *input, size_t input_len, int expected_id) { - int ret = 0; - const uint8_t *p; - EVP_PKEY *pkey = NULL; - - p = input; - pkey = d2i_AutoPrivateKey(NULL, &p, input_len); - if (pkey == NULL || p != input + input_len) { + const uint8_t *p = input; + ScopedEVP_PKEY pkey(d2i_AutoPrivateKey(NULL, &p, input_len)); + if (!pkey || p != input + input_len) { fprintf(stderr, "d2i_AutoPrivateKey failed\n"); - goto done; + return false; } - if (EVP_PKEY_id(pkey) != expected_id) { + if (EVP_PKEY_id(pkey.get()) != expected_id) { fprintf(stderr, "Did not decode expected type\n"); - goto done; + return false; } - ret = 1; - -done: - if (!ret) { - BIO_print_errors_fp(stderr); - } - - if (pkey != NULL) { - EVP_PKEY_free(pkey); - } - return ret; + return true; } -/* Tests loading a bad key in PKCS8 format */ -static int test_EVP_PKCS82PKEY(void) { - int ret = 0; +// TestEVP_PKCS82PKEY tests loading a bad key in PKCS8 format. +static bool TestEVP_PKCS82PKEY(void) { const uint8_t *derp = kExampleBadECKeyDER; - PKCS8_PRIV_KEY_INFO *p8inf = NULL; - EVP_PKEY *pkey = NULL; - - p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &derp, sizeof(kExampleBadECKeyDER)); - + ScopedPKCS8_PRIV_KEY_INFO p8inf( + d2i_PKCS8_PRIV_KEY_INFO(NULL, &derp, sizeof(kExampleBadECKeyDER))); if (!p8inf || derp != kExampleBadECKeyDER + sizeof(kExampleBadECKeyDER)) { fprintf(stderr, "Failed to parse key\n"); - goto done; + return false; } - pkey = EVP_PKCS82PKEY(p8inf); + ScopedEVP_PKEY pkey(EVP_PKCS82PKEY(p8inf.get())); if (pkey) { fprintf(stderr, "Imported invalid EC key\n"); - goto done; + return false; } - ret = 1; - -done: - if (p8inf != NULL) { - PKCS8_PRIV_KEY_INFO_free(p8inf); - } - - if (pkey != NULL) { - EVP_PKEY_free(pkey); - } - - return ret; + return true; } int main(void) { CRYPTO_library_init(); ERR_load_crypto_strings(); - if (!test_EVP_DigestSignInit()) { + if (!TestEVP_DigestSignInit()) { fprintf(stderr, "EVP_DigestSignInit failed\n"); + ERR_print_errors_fp(stderr); return 1; } - if (!test_EVP_DigestVerifyInit()) { + if (!TestEVP_DigestVerifyInit()) { fprintf(stderr, "EVP_DigestVerifyInit failed\n"); + ERR_print_errors_fp(stderr); return 1; } - if (!test_EVP_DigestSignAlgorithm()) { + if (!TestEVP_DigestSignAlgorithm()) { fprintf(stderr, "EVP_DigestSignInit failed\n"); + ERR_print_errors_fp(stderr); return 1; } - if (!test_EVP_DigestVerifyInitFromAlgorithm()) { + if (!TestEVP_DigestVerifyInitFromAlgorithm()) { fprintf(stderr, "EVP_DigestVerifyInitFromAlgorithm failed\n"); + ERR_print_errors_fp(stderr); return 1; } - if (!test_d2i_AutoPrivateKey(kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER), - EVP_PKEY_RSA)) { + if (!Testd2i_AutoPrivateKey(kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER), + EVP_PKEY_RSA)) { fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyDER) failed\n"); + ERR_print_errors_fp(stderr); return 1; } - if (!test_d2i_AutoPrivateKey(kExampleRSAKeyPKCS8, sizeof(kExampleRSAKeyPKCS8), - EVP_PKEY_RSA)) { + if (!Testd2i_AutoPrivateKey(kExampleRSAKeyPKCS8, sizeof(kExampleRSAKeyPKCS8), + EVP_PKEY_RSA)) { fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyPKCS8) failed\n"); + ERR_print_errors_fp(stderr); return 1; } - if (!test_d2i_AutoPrivateKey(kExampleECKeyDER, sizeof(kExampleECKeyDER), - EVP_PKEY_EC)) { + if (!Testd2i_AutoPrivateKey(kExampleECKeyDER, sizeof(kExampleECKeyDER), + EVP_PKEY_EC)) { fprintf(stderr, "d2i_AutoPrivateKey(kExampleECKeyDER) failed\n"); + ERR_print_errors_fp(stderr); + return 1; + } + + if (!Testd2i_AutoPrivateKey(kExampleDSAKeyDER, sizeof(kExampleDSAKeyDER), + EVP_PKEY_DSA)) { + fprintf(stderr, "d2i_AutoPrivateKey(kExampleDSAKeyDER) failed\n"); + ERR_print_errors_fp(stderr); return 1; } - if (!test_EVP_PKCS82PKEY()) { - fprintf(stderr, "test_EVP_PKCS82PKEY failed\n"); + if (!TestEVP_PKCS82PKEY()) { + fprintf(stderr, "TestEVP_PKCS82PKEY failed\n"); + ERR_print_errors_fp(stderr); return 1; } diff --git a/src/crypto/evp/evp_test.cc b/src/crypto/evp/evp_test.cc new file mode 100644 index 0000000..239f868 --- /dev/null +++ b/src/crypto/evp/evp_test.cc @@ -0,0 +1,262 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2015 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include <map> +#include <string> +#include <vector> + +#include <openssl/bio.h> +#include <openssl/crypto.h> +#include <openssl/digest.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <openssl/pem.h> + +#include "../test/file_test.h" +#include "../test/scoped_types.h" +#include "../test/stl_compat.h" + + +// evp_test dispatches between multiple test types. HMAC tests test the legacy +// EVP_PKEY_HMAC API. PrivateKey tests take a key name parameter and single +// block, decode it as a PEM private key, and save it under that key name. +// Decrypt, Sign, and Verify tests take a previously imported key name as +// parameter and test their respective operations. + +static const EVP_MD *GetDigest(FileTest *t, const std::string &name) { + if (name == "MD5") { + return EVP_md5(); + } else if (name == "SHA1") { + return EVP_sha1(); + } else if (name == "SHA224") { + return EVP_sha224(); + } else if (name == "SHA256") { + return EVP_sha256(); + } else if (name == "SHA384") { + return EVP_sha384(); + } else if (name == "SHA512") { + return EVP_sha512(); + } + t->PrintLine("Unknown digest: '%s'", name.c_str()); + return nullptr; +} + +using KeyMap = std::map<std::string, EVP_PKEY*>; + +// ImportPrivateKey evaluates a PrivateKey test in |t| and writes the resulting +// private key to |key_map|. +static bool ImportPrivateKey(FileTest *t, KeyMap *key_map) { + const std::string &key_name = t->GetParameter(); + if (key_map->count(key_name) > 0) { + t->PrintLine("Duplicate key '%s'.", key_name.c_str()); + return false; + } + const std::string &block = t->GetBlock(); + ScopedBIO bio(BIO_new_mem_buf(const_cast<char*>(block.data()), block.size())); + if (!bio) { + return false; + } + ScopedEVP_PKEY pkey(PEM_read_bio_PrivateKey(bio.get(), nullptr, 0, nullptr)); + if (!pkey) { + t->PrintLine("Error reading private key."); + return false; + } + (*key_map)[key_name] = pkey.release(); + return true; +} + +static bool TestHMAC(FileTest *t) { + std::string digest_str; + if (!t->GetAttribute(&digest_str, "HMAC")) { + return false; + } + const EVP_MD *digest = GetDigest(t, digest_str); + if (digest == nullptr) { + return false; + } + + std::vector<uint8_t> key, input, output; + if (!t->GetBytes(&key, "Key") || + !t->GetBytes(&input, "Input") || + !t->GetBytes(&output, "Output")) { + return false; + } + + ScopedEVP_PKEY pkey(EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, nullptr, + bssl::vector_data(&key), + key.size())); + ScopedEVP_MD_CTX mctx; + if (!pkey || + !EVP_DigestSignInit(mctx.get(), nullptr, digest, nullptr, pkey.get()) || + !EVP_DigestSignUpdate(mctx.get(), bssl::vector_data(&input), + input.size())) { + return false; + } + + size_t len; + std::vector<uint8_t> actual; + if (!EVP_DigestSignFinal(mctx.get(), nullptr, &len)) { + return false; + } + actual.resize(len); + if (!EVP_DigestSignFinal(mctx.get(), bssl::vector_data(&actual), &len)) { + return false; + } + actual.resize(len); + return t->ExpectBytesEqual(bssl::vector_data(&output), output.size(), + bssl::vector_data(&actual), actual.size()); +} + +static bool TestEVP(FileTest *t, void *arg) { + KeyMap *key_map = reinterpret_cast<KeyMap*>(arg); + if (t->GetType() == "PrivateKey") { + return ImportPrivateKey(t, key_map); + } else if (t->GetType() == "HMAC") { + return TestHMAC(t); + } + + int (*key_op_init)(EVP_PKEY_CTX *ctx); + int (*key_op)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len, + const uint8_t *in, size_t in_len); + if (t->GetType() == "Decrypt") { + key_op_init = EVP_PKEY_decrypt_init; + key_op = EVP_PKEY_decrypt; + } else if (t->GetType() == "Sign") { + key_op_init = EVP_PKEY_sign_init; + key_op = EVP_PKEY_sign; + } else if (t->GetType() == "Verify") { + key_op_init = EVP_PKEY_verify_init; + key_op = nullptr; // EVP_PKEY_verify is handled differently. + } else { + t->PrintLine("Unknown test '%s'", t->GetType().c_str()); + return false; + } + + // Load the key. + const std::string &key_name = t->GetParameter(); + if (key_map->count(key_name) == 0) { + t->PrintLine("Could not find key '%s'.", key_name.c_str()); + return false; + } + EVP_PKEY *key = (*key_map)[key_name]; + + std::vector<uint8_t> input, output; + if (!t->GetBytes(&input, "Input") || + !t->GetBytes(&output, "Output")) { + return false; + } + + // Set up the EVP_PKEY_CTX. + ScopedEVP_PKEY_CTX ctx(EVP_PKEY_CTX_new(key, nullptr)); + if (!ctx || !key_op_init(ctx.get())) { + return false; + } + if (t->HasAttribute("Digest")) { + const EVP_MD *digest = GetDigest(t, t->GetAttributeOrDie("Digest")); + if (digest == nullptr || + !EVP_PKEY_CTX_set_signature_md(ctx.get(), digest)) { + return false; + } + } + + if (t->GetType() == "Verify") { + if (!EVP_PKEY_verify(ctx.get(), bssl::vector_data(&output), output.size(), + bssl::vector_data(&input), input.size())) { + // ECDSA sometimes doesn't push an error code. Push one on the error queue + // so it's distinguishable from other errors. + ERR_put_error(ERR_LIB_USER, 0, ERR_R_EVP_LIB, __FILE__, __LINE__); + return false; + } + return true; + } + + size_t len; + std::vector<uint8_t> actual; + if (!key_op(ctx.get(), nullptr, &len, bssl::vector_data(&input), + input.size())) { + return false; + } + actual.resize(len); + if (!key_op(ctx.get(), bssl::vector_data(&actual), &len, + bssl::vector_data(&input), input.size())) { + return false; + } + actual.resize(len); + if (!t->ExpectBytesEqual(bssl::vector_data(&output), output.size(), + bssl::vector_data(&actual), len)) { + return false; + } + return true; +} + +int main(int argc, char **argv) { + CRYPTO_library_init(); + if (argc != 2) { + fprintf(stderr, "%s <test file.txt>\n", argv[0]); + return 1; + } + + KeyMap map; + int ret = FileTestMain(TestEVP, &map, argv[1]); + // TODO(davidben): When we can rely on a move-aware std::map, make KeyMap a + // map of ScopedEVP_PKEY instead. + for (const auto &pair : map) { + EVP_PKEY_free(pair.second); + } + return ret; +} diff --git a/src/crypto/evp/evp_tests.txt b/src/crypto/evp/evp_tests.txt new file mode 100644 index 0000000..cccfa4f --- /dev/null +++ b/src/crypto/evp/evp_tests.txt @@ -0,0 +1,174 @@ +# Public key algorithm tests + +# Private keys used for PKEY operations. + +# RSA 2048 bit key. + +PrivateKey = RSA-2048 +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDNAIHqeyrh6gbV +n3xz2f+5SglhXC5Lp8Y2zvCN01M+wxhVJbAVx2m5mnfWclv5w1Mqm25fZifV+4UW +B2jT3anL01l0URcX3D0wnS/EfuQfl+Mq23+d2GShxHZ6Zm7NcbwarPXnUX9LOFlP +6psF5C1a2pkSAIAT5FMWpNm7jtCGuI0odYusr5ItRqhotIXSOcm66w4rZFknEPQr +LR6gpLSALAvsqzKPimiwBzvbVG/uqYCdKEmRKzkMFTK8finHZY+BdfrkbzQzL/h7 +yrPkBkm5hXeGnaDqcYNT8HInVIhpE2SHYNEivmduD8SD3SD/wxvalqMZZsmqLnWt +A95H4cRPAgMBAAECggEAYCl6x5kbFnoG1rJHWLjL4gi+ubLZ7Jc4vYD5Ci41AF3X +ziktnim6iFvTFv7x8gkTvArJDWsICLJBTYIQREHYYkozzgIzyPeApIs3Wv8C12cS +IopwJITbP56+zM+77hcJ26GCgA2Unp5CFuC/81WDiPi9kNo3Oh2CdD7D+90UJ/0W +glplejFpEuhpU2URfKL4RckJQF/KxV+JX8FdIDhsJu54yemQdQKaF4psHkzwwgDo +qc+yfp0Vb4bmwq3CKxqEoc1cpbJ5CHXXlAfISzUjlcuBzD/tW7BDtp7eDAcgRVAC +XO6MX0QBcLYSC7SOD3R7zY9SIRCFDfBDxCjf0YcFMQKBgQD2+WG0fLwDXTrt68fe +hQqVa2Xs25z2B2QGPxWqSFU8WNly/mZ1BW413f3De/O58vYi7icTNyVoScm+8hdv +6PfD+LuRujdN1TuvPeyBTSvewQwf3IjN0Wh28mse36PwlBl+301C/x+ylxEDuJjK +hZxCcocIaoQqtBC7ac8tNa9r4wKBgQDUfnJKf/QQSLJwwlJKQQGHi3MVm7c9PbwY +eyIOY1s1NPluJDoYTZP4YLa/u2txwe2aHh9FhYMCPDAelqaSwaCLU9DsnKkQEA2A +RR47fcagG6xK7O+N95iEa8I1oIy7os9MBoBMwRIZ6VYIxxTj8UMNSR+tu6MqV1Gg +T5d0WDTJpQKBgCHyRSu5uV39AoyRS/eZ8cp36JqV1Q08FtOE+EVfi9evnrPfo9WR +2YQt7yNfdjCo5IwIj/ZkLhAXlFNakz4el2+oUJ/HKLLaDEoaCNf883q6rh/zABrK +HcG7sF2d/7qhoJ9/se7zgjfZ68zHIrkzhDbd5xGREnmMJoCcGo3sQyBhAoGAH3UQ +qmLC2N5KPFMoJ4H0HgLQ6LQCrnhDLkScSBEBYaEUA/AtAYgKjcyTgVLXlyGkcRpg +esRHHr+WSBD5W+R6ReYEmeKfTJdzyDdzQE9gZjdyjC0DUbsDwybIu3OnIef6VEDq +IXK7oUZfzDDcsNn4mTDoFaoff5cpqFfgDgM43VkCgYBNHw11b+d+AQmaZS9QqIt7 +aF3FvwCYHV0jdv0Mb+Kc1bY4c0R5MFpzrTwVmdOerjuuA1+9b+0Hwo3nBZM4eaBu +SOamA2hu2OJWCl9q8fLCT69KqWDjghhvFe7c6aJJGucwaA3Uz3eLcPqoaCarMiNH +fMkTd7GabVourqIZdgvu1Q== +-----END PRIVATE KEY----- + +# EC P-256 key + +PrivateKey = P-256 +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgiocvtiiTxNH/xbnw ++RdYBp+DUuCPoFpJ+NuSbLVyhyWhRANCAAQsFQ9CnOcPIWwlLPXgYs4fY5zV0WXH ++JQkBywnGX14szuSDpXNtmTpkNzwz+oNlOKo5q+dDlgFbmUxBJJbn+bJ +-----END PRIVATE KEY----- + +# RSA tests + +Sign = RSA-2048 +Digest = SHA1 +Input = "0123456789ABCDEF1234" +Output = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad + +Verify = RSA-2048 +Digest = SHA1 +Input = "0123456789ABCDEF1234" +Output = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad + +# Digest too long +Sign = RSA-2048 +Digest = SHA1 +Input = "0123456789ABCDEF12345" +Output = +Error = INVALID_DIGEST_LENGTH + +# Digest too short +Sign = RSA-2048 +Digest = SHA1 +Input = "0123456789ABCDEF12345" +Output = +Error = INVALID_DIGEST_LENGTH + +# Mismatched digest +Verify = RSA-2048 +Digest = SHA1 +Input = "0123456789ABCDEF1233" +Output = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad +Error = BAD_SIGNATURE + +# Corrupted signature +Verify = RSA-2048 +Digest = SHA1 +Input = "0123456789ABCDEF1233" +Output = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ae +Error = BLOCK_TYPE_IS_NOT_01 + +# parameter missing (NOTE: this differs from upstream) +Verify = RSA-2048 +Digest = SHA1 +Input = "0123456789ABCDEF1234" +Output = 3ec3fc29eb6e122bd7aa361cd09fe1bcbe85311096a7b9e4799cedfb2351ce0ab7fe4e75b4f6b37f67edd9c60c800f9ab941c0c157d7d880ca9de40c951d60fd293ae220d4bc510b1572d6e85a1bbbd8605b52e05f1c64fafdae59a1c2fbed214b7844d0134619de62851d5a0522e32e556e5950f3f97b8150e3f0dffee612c924201c27cd9bc8b423a71533380c276d3d59fcba35a2e80a1a192ec266a6c2255012cd86a349fe90a542b355fa3355b04da6cdf1df77f0e7bd44a90e880e1760266d233e465226f5db1c68857847d82072861ee266ddfc2e596845b77e1803274a579835ab5e4975d81d20b7df9cec7795489e4a2bdb8c1cf6a6b359945ac92c +Error = BAD_SIGNATURE + +# embedded digest too long +Verify = RSA-2048 +Digest = SHA1 +Input = "0123456789ABCDEF1234" +Output = afec9a0d5330a08f54283bb4a9d4e7e7e70fc1342336c4c766fba713f66970151c6e27413c48c33864ea45a0238787004f338ed3e21b53b0fe9c1151c42c388cbc7cba5a06b706c407a5b48324fbe994dc7afc3a19fb3d2841e66222596c14cd72a0f0a7455a019d8eb554f59c0183f9552b75aa96fee8bf935945e079ca283d2bd3534a86f11351f6d6181fbf433e5b01a6d1422145c7a72214d3aacdd5d3af12b2d6bf6438f9f9a64010d8aeed801c87f0859412b236150b86a545f7239be022f4a7ad246b59df87514294cb4a4c7c5a997ee53c66054d9f38ca4e76c1f7af83c30f737ef70f83a45aebe18238ddb95e1998814ca4fc72388f1533147c169d +Error = BAD_SIGNATURE + +# embedded digest too short +Verify = RSA-2048 +Digest = SHA1 +Input = "0123456789ABCDEF1234" +Output = afec9a0d5330a08f54283bb4a9d4e7e7e70fc1342336c4c766fba713f66970151c6e27413c48c33864ea45a0238787004f338ed3e21b53b0fe9c1151c42c388cbc7cba5a06b706c407a5b48324fbe994dc7afc3a19fb3d2841e66222596c14cd72a0f0a7455a019d8eb554f59c0183f9552b75aa96fee8bf935945e079ca283d2bd3534a86f11351f6d6181fbf433e5b01a6d1422145c7a72214d3aacdd5d3af12b2d6bf6438f9f9a64010d8aeed801c87f0859412b236150b86a545f7239be022f4a7ad246b59df87514294cb4a4c7c5a997ee53c66054d9f38ca4e76c1f7af83c30f737ef70f83a45aebe18238ddb95e1998814ca4fc72388f1533147c169d +Error = BAD_SIGNATURE + +# Garbage after DigestInfo +Verify = RSA-2048 +Digest = SHA1 +Input = "0123456789ABCDEF1234" +Output = 9ee34872d4271a7d8808af0a4052a145a6d6a8437d00da3ed14428c7f087cd39f4d43334c41af63e7fa1ba363fee7bcef401d9d36a662abbab55ce89a696e1be0dfa19a5d09ca617dd488787b6048baaefeb29bc8688b2fe3882de2b77c905b5a8b56cf9616041e5ec934ba6de863efe93acc4eef783fe7f72a00fa65d6093ed32bf98ce527e62ccb1d56317f4be18b7e0f55d7c36617d2d0678a306e3350956b662ac15df45215dd8f6b314babb9788e6c272fa461e4c9b512a11a4b92bc77c3a4c95c903fccb238794eca5c750477bf56ea6ee6a167367d881b485ae3889e7c489af8fdf38e0c0f2aed780831182e34abedd43c39281b290774bf35cc25274 +Error = BAD_SIGNATURE + +# invalid tag for parameter +Verify = RSA-2048 +Digest = SHA1 +Input = "0123456789ABCDEF1234" +Output = 49525db4d44c755e560cba980b1d85ea604b0e077fcadd4ba44072a3487bbddb835016200a7d8739cce2dc3223d9c20cbdd25059ab02277f1f21318efd18e21038ec89aa9d40680987129e8b41ba33bceb86518bdf47268b921cce2037acabca6575d832499538d6f40cdba0d40bd7f4d8ea6ca6e2eec87f294efc971407857f5d7db09f6a7b31e301f571c6d82a5e3d08d2bb3a36e673d28b910f5bec57f0fcc4d968fd7c94d0b9226dec17f5192ad8b42bcab6f26e1bea1fdc3b958199acb00f14ebcb2a352f3afcedd4c09000128a603bbeb9696dea13040445253972d46237a25c7845e3b464e6984c2348ea1f1210a9ff0b00d2d72b50db00c009bb39f9 +Error = BAD_SIGNATURE + +# EC tests + +Verify = P-256 +Digest = SHA1 +Input = "0123456789ABCDEF1234" +Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8 + +# Digest too long +Verify = P-256 +Digest = SHA1 +Input = "0123456789ABCDEF12345" +Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8 +# This operation fails without an error code, so ERR_R_EVP_LIB is surfaced. +Error = public key routines + +# Digest too short +Verify = P-256 +Digest = SHA1 +Input = "0123456789ABCDEF123" +Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8 +# This operation fails without an error code, so ERR_R_EVP_LIB is surfaced. +Error = public key routines + +# Digest invalid +Verify = P-256 +Digest = SHA1 +Input = "0123456789ABCDEF1235" +Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8 +# This operation fails without an error code, so ERR_R_EVP_LIB is surfaced. +Error = public key routines + +# Invalid signature +Verify = P-256 +Digest = SHA1 +Input = "0123456789ABCDEF1234" +Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec7 +# This operation fails without an error code, so ERR_R_EVP_LIB is surfaced. +Error = public key routines + +# Garbage after signature +Verify = P-256 +Digest = SHA1 +Input = "0123456789ABCDEF1234" +Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec800 +# This operation fails without an error code, so ERR_R_EVP_LIB is surfaced. +Error = public key routines + +# BER signature +Verify = P-256 +Digest = SHA1 +Input = "0123456789ABCDEF1234" +Output = 3080022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec80000 +# This operation fails without an error code, so ERR_R_EVP_LIB is surfaced. +Error = public key routines diff --git a/src/crypto/evp/internal.h b/src/crypto/evp/internal.h index 2b0f608..08a7bfb 100644 --- a/src/crypto/evp/internal.h +++ b/src/crypto/evp/internal.h @@ -170,8 +170,49 @@ typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx); #define EVP_PKEY_OP_TYPE_GEN (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN) +/* EVP_PKEY_CTX_ctrl performs |cmd| on |ctx|. The |keytype| and |optype| + * arguments can be -1 to specify that any type and operation are acceptable, + * otherwise |keytype| must match the type of |ctx| and the bits of |optype| + * must intersect the operation flags set on |ctx|. + * + * The |p1| and |p2| arguments depend on the value of |cmd|. + * + * It returns one on success and zero on error. */ +OPENSSL_EXPORT int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, int p1, void *p2); + +/* EVP_PKEY_CTRL_DIGESTINIT is an internal value. It's called by + * EVP_DigestInit_ex to signal the |EVP_PKEY| that a digest operation is + * starting. + * + * TODO(davidben): This is only needed to support the deprecated HMAC |EVP_PKEY| + * types. */ +#define EVP_PKEY_CTRL_DIGESTINIT 3 + +/* EVP_PKEY_CTRL_PEER_KEY is called with different values of |p1|: + * 0: Is called from |EVP_PKEY_derive_set_peer| and |p2| contains a peer key. + * If the return value is <= 0, the key is rejected. + * 1: Is called at the end of |EVP_PKEY_derive_set_peer| and |p2| contains a + * peer key. If the return value is <= 0, the key is rejected. + * 2: Is called with |p2| == NULL to test whether the peer's key was used. + * (EC)DH always return one in this case. + * 3: Is called with |p2| == NULL to set whether the peer's key was used. + * (EC)DH always return one in this case. This was only used for GOST. */ +#define EVP_PKEY_CTRL_PEER_KEY 4 + +/* EVP_PKEY_CTRL_SET_MAC_KEY sets a MAC key. For example, this can be done an + * |EVP_PKEY_CTX| prior to calling |EVP_PKEY_keygen| in order to generate an + * HMAC |EVP_PKEY| with the given key. It returns one on success and zero on + * error. */ +#define EVP_PKEY_CTRL_SET_MAC_KEY 5 + +/* EVP_PKEY_ALG_CTRL is the base value from which key-type specific ctrl + * commands are numbered. */ +#define EVP_PKEY_ALG_CTRL 0x1000 + #define EVP_PKEY_CTRL_MD 1 #define EVP_PKEY_CTRL_GET_MD 2 + #define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1) #define EVP_PKEY_CTRL_GET_RSA_PADDING (EVP_PKEY_ALG_CTRL + 2) #define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 3) @@ -185,6 +226,8 @@ typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx); #define EVP_PKEY_CTRL_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 11) #define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12) +#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1) + struct evp_pkey_ctx_st { /* Method associated with this operation */ const EVP_PKEY_METHOD *pmeth; diff --git a/src/crypto/evp/p_dsa_asn1.c b/src/crypto/evp/p_dsa_asn1.c new file mode 100644 index 0000000..0ac7da7 --- /dev/null +++ b/src/crypto/evp/p_dsa_asn1.c @@ -0,0 +1,569 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#include <openssl/evp.h> + +#include <openssl/asn1.h> +#include <openssl/asn1t.h> +#include <openssl/digest.h> +#include <openssl/dsa.h> +#include <openssl/err.h> +#include <openssl/mem.h> +#include <openssl/obj.h> +#include <openssl/x509.h> + +#include "../dsa/internal.h" +#include "internal.h" + + +static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { + const uint8_t *p, *pm; + int pklen, pmlen; + int ptype; + void *pval; + ASN1_STRING *pstr; + X509_ALGOR *palg; + ASN1_INTEGER *public_key = NULL; + + DSA *dsa = NULL; + + if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) { + return 0; + } + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + if (ptype == V_ASN1_SEQUENCE) { + pstr = pval; + pm = pstr->data; + pmlen = pstr->length; + + dsa = d2i_DSAparams(NULL, &pm, pmlen); + if (dsa == NULL) { + OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, EVP_R_DECODE_ERROR); + goto err; + } + } else if (ptype == V_ASN1_NULL || ptype == V_ASN1_UNDEF) { + dsa = DSA_new(); + if (dsa == NULL) { + OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, ERR_R_MALLOC_FAILURE); + goto err; + } + } else { + OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, EVP_R_PARAMETER_ENCODING_ERROR); + goto err; + } + + public_key = d2i_ASN1_INTEGER(NULL, &p, pklen); + if (public_key == NULL) { + OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, EVP_R_DECODE_ERROR); + goto err; + } + + dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL); + if (dsa->pub_key == NULL) { + OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, EVP_R_BN_DECODE_ERROR); + goto err; + } + + ASN1_INTEGER_free(public_key); + EVP_PKEY_assign_DSA(pkey, dsa); + return 1; + +err: + ASN1_INTEGER_free(public_key); + DSA_free(dsa); + return 0; +} + +static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { + DSA *dsa; + void *pval = NULL; + uint8_t *penc = NULL; + int penclen; + + dsa = pkey->pkey.dsa; + dsa->write_params = 0; + + penclen = i2d_DSAPublicKey(dsa, &penc); + + if (penclen <= 0) { + OPENSSL_PUT_ERROR(EVP, dsa_pub_encode, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), V_ASN1_UNDEF, pval, + penc, penclen)) { + return 1; + } + +err: + OPENSSL_free(penc); + ASN1_STRING_free(pval); + + return 0; +} + +static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { + const uint8_t *p, *pm; + int pklen, pmlen; + int ptype; + void *pval; + ASN1_STRING *pstr; + X509_ALGOR *palg; + ASN1_INTEGER *privkey = NULL; + BN_CTX *ctx = NULL; + + /* In PKCS#8 DSA: you just get a private key integer and parameters in the + * AlgorithmIdentifier the pubkey must be recalculated. */ + + STACK_OF(ASN1_TYPE) *ndsa = NULL; + DSA *dsa = NULL; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) { + return 0; + } + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + /* Check for broken DSA PKCS#8, UGH! */ + if (*p == (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) { + ASN1_TYPE *t1, *t2; + ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen); + if (ndsa == NULL) { + goto decerr; + } + if (sk_ASN1_TYPE_num(ndsa) != 2) { + goto decerr; + } + + /* Handle Two broken types: + * SEQUENCE {parameters, priv_key} + * SEQUENCE {pub_key, priv_key}. */ + + t1 = sk_ASN1_TYPE_value(ndsa, 0); + t2 = sk_ASN1_TYPE_value(ndsa, 1); + if (t1->type == V_ASN1_SEQUENCE) { + p8->broken = PKCS8_EMBEDDED_PARAM; + pval = t1->value.ptr; + } else if (ptype == V_ASN1_SEQUENCE) { + p8->broken = PKCS8_NS_DB; + } else { + goto decerr; + } + + if (t2->type != V_ASN1_INTEGER) { + goto decerr; + } + + privkey = t2->value.integer; + } else { + const uint8_t *q = p; + privkey = d2i_ASN1_INTEGER(NULL, &p, pklen); + if (privkey == NULL) { + goto decerr; + } + if (privkey->type == V_ASN1_NEG_INTEGER) { + p8->broken = PKCS8_NEG_PRIVKEY; + ASN1_INTEGER_free(privkey); + privkey = d2i_ASN1_UINTEGER(NULL, &q, pklen); + if (privkey == NULL) { + goto decerr; + } + } + if (ptype != V_ASN1_SEQUENCE) { + goto decerr; + } + } + + pstr = pval; + pm = pstr->data; + pmlen = pstr->length; + dsa = d2i_DSAparams(NULL, &pm, pmlen); + if (dsa == NULL) { + goto decerr; + } + /* We have parameters. Now set private key */ + dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL); + if (dsa->priv_key == NULL) { + OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, ERR_LIB_BN); + goto dsaerr; + } + /* Calculate public key. */ + dsa->pub_key = BN_new(); + if (dsa->pub_key == NULL) { + OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, ERR_R_MALLOC_FAILURE); + goto dsaerr; + } + ctx = BN_CTX_new(); + if (ctx == NULL) { + OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, ERR_R_MALLOC_FAILURE); + goto dsaerr; + } + + if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { + OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, ERR_LIB_BN); + goto dsaerr; + } + + EVP_PKEY_assign_DSA(pkey, dsa); + BN_CTX_free(ctx); + sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); + ASN1_INTEGER_free(privkey); + + return 1; + +decerr: + OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, EVP_R_DECODE_ERROR); + +dsaerr: + BN_CTX_free(ctx); + ASN1_INTEGER_free(privkey); + sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); + DSA_free(dsa); + return 0; +} + +static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { + ASN1_STRING *params = NULL; + ASN1_INTEGER *prkey = NULL; + uint8_t *dp = NULL; + int dplen; + + if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key) { + OPENSSL_PUT_ERROR(EVP, dsa_priv_encode, EVP_R_MISSING_PARAMETERS); + goto err; + } + + params = ASN1_STRING_new(); + if (!params) { + OPENSSL_PUT_ERROR(EVP, dsa_priv_encode, ERR_R_MALLOC_FAILURE); + goto err; + } + + params->length = i2d_DSAparams(pkey->pkey.dsa, ¶ms->data); + if (params->length <= 0) { + OPENSSL_PUT_ERROR(EVP, dsa_priv_encode, ERR_R_MALLOC_FAILURE); + goto err; + } + params->type = V_ASN1_SEQUENCE; + + /* Get private key into integer. */ + prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL); + + if (!prkey) { + OPENSSL_PUT_ERROR(EVP, dsa_priv_encode, ERR_LIB_BN); + goto err; + } + + dplen = i2d_ASN1_INTEGER(prkey, &dp); + + ASN1_INTEGER_free(prkey); + + if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_dsa), 0, + V_ASN1_SEQUENCE, params, dp, dplen)) { + goto err; + } + + return 1; + +err: + OPENSSL_free(dp); + ASN1_STRING_free(params); + ASN1_INTEGER_free(prkey); + return 0; +} + +static int int_dsa_size(const EVP_PKEY *pkey) { + return DSA_size(pkey->pkey.dsa); +} + +static int dsa_bits(const EVP_PKEY *pkey) { + return BN_num_bits(pkey->pkey.dsa->p); +} + +static int dsa_missing_parameters(const EVP_PKEY *pkey) { + DSA *dsa; + dsa = pkey->pkey.dsa; + if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) { + return 1; + } + return 0; +} + +static int dup_bn_into(BIGNUM **out, BIGNUM *src) { + BIGNUM *a; + + a = BN_dup(src); + if (a == NULL) { + return 0; + } + BN_free(*out); + *out = a; + + return 1; +} + +static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { + if (!dup_bn_into(&to->pkey.dsa->p, from->pkey.dsa->p) || + !dup_bn_into(&to->pkey.dsa->q, from->pkey.dsa->q) || + !dup_bn_into(&to->pkey.dsa->g, from->pkey.dsa->g)) { + return 0; + } + + return 1; +} + +static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { + return BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) == 0 && + BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) == 0 && + BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g) == 0; +} + +static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { + return BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) == 0; +} + +static void int_dsa_free(EVP_PKEY *pkey) { DSA_free(pkey->pkey.dsa); } + +static void update_buflen(const BIGNUM *b, size_t *pbuflen) { + size_t i; + + if (!b) { + return; + } + i = BN_num_bytes(b); + if (*pbuflen < i) { + *pbuflen = i; + } +} + +static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) { + uint8_t *m = NULL; + int ret = 0; + size_t buf_len = 0; + const char *ktype = NULL; + + const BIGNUM *priv_key, *pub_key; + + priv_key = NULL; + if (ptype == 2) { + priv_key = x->priv_key; + } + + pub_key = NULL; + if (ptype > 0) { + pub_key = x->pub_key; + } + + ktype = "DSA-Parameters"; + if (ptype == 2) { + ktype = "Private-Key"; + } else if (ptype == 1) { + ktype = "Public-Key"; + } + + update_buflen(x->p, &buf_len); + update_buflen(x->q, &buf_len); + update_buflen(x->g, &buf_len); + update_buflen(priv_key, &buf_len); + update_buflen(pub_key, &buf_len); + + m = (uint8_t *)OPENSSL_malloc(buf_len + 10); + if (m == NULL) { + OPENSSL_PUT_ERROR(EVP, do_dsa_print, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (priv_key) { + if (!BIO_indent(bp, off, 128) || + BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) { + goto err; + } + } + + if (!ASN1_bn_print(bp, "priv:", priv_key, m, off) || + !ASN1_bn_print(bp, "pub: ", pub_key, m, off) || + !ASN1_bn_print(bp, "P: ", x->p, m, off) || + !ASN1_bn_print(bp, "Q: ", x->q, m, off) || + !ASN1_bn_print(bp, "G: ", x->g, m, off)) { + goto err; + } + ret = 1; + +err: + OPENSSL_free(m); + return ret; +} + +static int dsa_param_decode(EVP_PKEY *pkey, const uint8_t **pder, int derlen) { + DSA *dsa; + dsa = d2i_DSAparams(NULL, pder, derlen); + if (dsa == NULL) { + OPENSSL_PUT_ERROR(EVP, dsa_param_decode, ERR_R_DSA_LIB); + return 0; + } + EVP_PKEY_assign_DSA(pkey, dsa); + return 1; +} + +static int dsa_param_encode(const EVP_PKEY *pkey, uint8_t **pder) { + return i2d_DSAparams(pkey->pkey.dsa, pder); +} + +static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) { + return do_dsa_print(bp, pkey->pkey.dsa, indent, 0); +} + +static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) { + return do_dsa_print(bp, pkey->pkey.dsa, indent, 1); +} + +static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) { + return do_dsa_print(bp, pkey->pkey.dsa, indent, 2); +} + +static int old_dsa_priv_decode(EVP_PKEY *pkey, const uint8_t **pder, + int derlen) { + DSA *dsa; + dsa = d2i_DSAPrivateKey(NULL, pder, derlen); + if (dsa == NULL) { + OPENSSL_PUT_ERROR(EVP, old_dsa_priv_decode, ERR_R_DSA_LIB); + return 0; + } + EVP_PKEY_assign_DSA(pkey, dsa); + return 1; +} + +static int old_dsa_priv_encode(const EVP_PKEY *pkey, uint8_t **pder) { + return i2d_DSAPrivateKey(pkey->pkey.dsa, pder); +} + +static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, + const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) { + DSA_SIG *dsa_sig; + const uint8_t *p; + + if (!sig) { + return BIO_puts(bp, "\n") > 0; + } + + p = sig->data; + dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length); + if (dsa_sig == NULL) { + return X509_signature_dump(bp, sig, indent); + } + + int rv = 0; + size_t buf_len = 0; + uint8_t *m = NULL; + + update_buflen(dsa_sig->r, &buf_len); + update_buflen(dsa_sig->s, &buf_len); + m = OPENSSL_malloc(buf_len + 10); + if (m == NULL) { + OPENSSL_PUT_ERROR(EVP, dsa_sig_print, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (BIO_write(bp, "\n", 1) != 1 || + !ASN1_bn_print(bp, "r: ", dsa_sig->r, m, indent) || + !ASN1_bn_print(bp, "s: ", dsa_sig->s, m, indent)) { + goto err; + } + rv = 1; + +err: + OPENSSL_free(m); + DSA_SIG_free(dsa_sig); + return rv; +} + +const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = { + EVP_PKEY_DSA, + EVP_PKEY_DSA, + 0, + + "DSA", + "OpenSSL DSA method", + + dsa_pub_decode, + dsa_pub_encode, + dsa_pub_cmp, + dsa_pub_print, + + dsa_priv_decode, + dsa_priv_encode, + dsa_priv_print, + + NULL /* pkey_opaque */, + NULL /* pkey_supports_digest */, + + int_dsa_size, + dsa_bits, + + dsa_param_decode, + dsa_param_encode, + dsa_missing_parameters, + dsa_copy_parameters, + dsa_cmp_parameters, + dsa_param_print, + dsa_sig_print, + + int_dsa_free, + old_dsa_priv_decode, + old_dsa_priv_encode, +}; diff --git a/src/crypto/evp/p_ec.c b/src/crypto/evp/p_ec.c index c274131..73c00d8 100644 --- a/src/crypto/evp/p_ec.c +++ b/src/crypto/evp/p_ec.c @@ -119,9 +119,7 @@ static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) { return; } - if (dctx->gen_group) { - EC_GROUP_free(dctx->gen_group); - } + EC_GROUP_free(dctx->gen_group); OPENSSL_free(dctx); } @@ -212,8 +210,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { OPENSSL_PUT_ERROR(EVP, pkey_ec_ctrl, EVP_R_INVALID_CURVE); return 0; } - if (dctx->gen_group) - EC_GROUP_free(dctx->gen_group); + EC_GROUP_free(dctx->gen_group); dctx->gen_group = group; return 1; @@ -240,7 +237,8 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { return 1; default: - return -2; + OPENSSL_PUT_ERROR(EVP, pkey_ec_ctrl, EVP_R_COMMAND_NOT_SUPPORTED); + return 0; } } diff --git a/src/crypto/evp/p_ec_asn1.c b/src/crypto/evp/p_ec_asn1.c index 914cc2f..fbbf4e7 100644 --- a/src/crypto/evp/p_ec_asn1.c +++ b/src/crypto/evp/p_ec_asn1.c @@ -142,23 +142,13 @@ static EC_KEY *eckey_type2param(int ptype, void *pval) { } } else if (ptype == V_ASN1_OBJECT) { ASN1_OBJECT *poid = pval; - EC_GROUP *group; /* type == V_ASN1_OBJECT => the parameters are given * by an asn1 OID */ - eckey = EC_KEY_new(); + eckey = EC_KEY_new_by_curve_name(OBJ_obj2nid(poid)); if (eckey == NULL) { - OPENSSL_PUT_ERROR(EVP, eckey_type2param, ERR_R_MALLOC_FAILURE); goto err; } - group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid)); - if (group == NULL) { - goto err; - } - if (EC_KEY_set_group(eckey, group) == 0) { - goto err; - } - EC_GROUP_free(group); } else { OPENSSL_PUT_ERROR(EVP, eckey_type2param, EVP_R_DECODE_ERROR); goto err; @@ -201,8 +191,9 @@ static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { return 1; err: - if (eckey) + if (eckey) { EC_KEY_free(eckey); + } return 0; } @@ -235,8 +226,9 @@ static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { eckey = eckey_type2param(ptype, pval); - if (!eckey) + if (!eckey) { goto ecliberr; + } /* We have parameters now set private key */ if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { @@ -282,8 +274,9 @@ static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { ecliberr: OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB); ecerr: - if (eckey) + if (eckey) { EC_KEY_free(eckey); + } return 0; } @@ -439,10 +432,12 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) { if (ktype == 2) { priv_key = EC_KEY_get0_private_key(x); - if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) + if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) { buf_len = i; - } else + } + } else { priv_key = NULL; + } if (ktype > 0) { buf_len += 10; @@ -451,24 +446,27 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) { goto err; } } - if (ktype == 2) + if (ktype == 2) { ecstr = "Private-Key"; - else if (ktype == 1) + } else if (ktype == 1) { ecstr = "Public-Key"; - else + } else { ecstr = "ECDSA-Parameters"; + } - if (!BIO_indent(bp, off, 128)) - goto err; - if ((order = BN_new()) == NULL) - goto err; - if (!EC_GROUP_get_order(group, order, NULL)) + if (!BIO_indent(bp, off, 128)) { goto err; - if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) + } + order = BN_new(); + if (order == NULL || !EC_GROUP_get_order(group, order, NULL) || + BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) { goto err; + } - if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, buffer, off)) + if ((priv_key != NULL) && + !ASN1_bn_print(bp, "priv:", priv_key, buffer, off)) { goto err; + } if (pub_key_bytes != NULL) { BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off); } @@ -479,16 +477,13 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) { ret = 1; err: - if (!ret) + if (!ret) { OPENSSL_PUT_ERROR(EVP, do_EC_KEY_print, reason); - if (pub_key_bytes) - OPENSSL_free(pub_key_bytes); - if (order) - BN_free(order); - if (ctx) - BN_CTX_free(ctx); - if (buffer != NULL) - OPENSSL_free(buffer); + } + OPENSSL_free(pub_key_bytes); + BN_free(order); + BN_CTX_free(ctx); + OPENSSL_free(buffer); return ret; } diff --git a/src/crypto/evp/p_hmac.c b/src/crypto/evp/p_hmac.c index 6d9a909..21703ed 100644 --- a/src/crypto/evp/p_hmac.c +++ b/src/crypto/evp/p_hmac.c @@ -204,7 +204,8 @@ static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { break; default: - return -2; + OPENSSL_PUT_ERROR(EVP, pkey_hmac_ctrl, EVP_R_COMMAND_NOT_SUPPORTED); + return 0; } return 1; } diff --git a/src/crypto/evp/p_rsa.c b/src/crypto/evp/p_rsa.c index 31f5aaa..5abc075 100644 --- a/src/crypto/evp/p_rsa.c +++ b/src/crypto/evp/p_rsa.c @@ -55,10 +55,12 @@ #include <openssl/evp.h> +#include <limits.h> #include <string.h> #include <openssl/bn.h> #include <openssl/buf.h> +#include <openssl/bytestring.h> #include <openssl/digest.h> #include <openssl/err.h> #include <openssl/mem.h> @@ -125,9 +127,7 @@ static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { dctx->md = sctx->md; dctx->mgf1md = sctx->mgf1md; if (sctx->oaep_label) { - if (dctx->oaep_label) { - OPENSSL_free(dctx->oaep_label); - } + OPENSSL_free(dctx->oaep_label); dctx->oaep_label = BUF_memdup(sctx->oaep_label, sctx->oaep_labellen); if (!dctx->oaep_label) { return 0; @@ -145,15 +145,9 @@ static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) { return; } - if (rctx->pub_exp) { - BN_free(rctx->pub_exp); - } - if (rctx->tbuf) { - OPENSSL_free(rctx->tbuf); - } - if (rctx->oaep_label) { - OPENSSL_free(rctx->oaep_label); - } + BN_free(rctx->pub_exp); + OPENSSL_free(rctx->tbuf); + OPENSSL_free(rctx->oaep_label); OPENSSL_free(rctx); } @@ -369,7 +363,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { 0 == (ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))) { OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); - return -2; + return 0; } if ((p1 == RSA_PKCS1_PSS_PADDING || p1 == RSA_PKCS1_OAEP_PADDING) && rctx->md == NULL) { @@ -386,13 +380,13 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN: if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PSS_SALTLEN); - return -2; + return 0; } if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) { *(int *)p2 = rctx->saltlen; } else { if (p1 < -2) { - return -2; + return 0; } rctx->saltlen = p1; } @@ -401,14 +395,14 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: if (p1 < 256) { OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_KEYBITS); - return -2; + return 0; } rctx->nbits = p1; return 1; case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: if (!p2) { - return -2; + return 0; } BN_free(rctx->pub_exp); rctx->pub_exp = p2; @@ -418,7 +412,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { case EVP_PKEY_CTRL_GET_RSA_OAEP_MD: if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE); - return -2; + return 0; } if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD) { *(const EVP_MD **)p2 = rctx->md; @@ -443,7 +437,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING && rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_MGF1_MD); - return -2; + return 0; } if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) { if (rctx->mgf1md) { @@ -459,11 +453,9 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { case EVP_PKEY_CTRL_RSA_OAEP_LABEL: if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE); - return -2; - } - if (rctx->oaep_label) { - OPENSSL_free(rctx->oaep_label); + return 0; } + OPENSSL_free(rctx->oaep_label); if (p2 && p1 > 0) { /* TODO(fork): this seems wrong. Shouldn't it take a copy of the * buffer? */ @@ -478,16 +470,17 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE); - return -2; + return 0; } - *(uint8_t **)p2 = rctx->oaep_label; - return rctx->oaep_labellen; + CBS_init((CBS *)p2, rctx->oaep_label, rctx->oaep_labellen); + return 1; case EVP_PKEY_CTRL_DIGESTINIT: return 1; default: - return -2; + OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_COMMAND_NOT_SUPPORTED); + return 0; } } @@ -497,8 +490,9 @@ static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { if (!rctx->pub_exp) { rctx->pub_exp = BN_new(); - if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4)) + if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4)) { return 0; + } } rsa = RSA_new(); if (!rsa) { @@ -583,7 +577,7 @@ int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, const uint8_t *label, size_t label_len) { int label_len_int = label_len; if (((size_t) label_len_int) != label_len) { - return -2; + return 0; } return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, @@ -593,6 +587,15 @@ int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, const uint8_t *label, int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, const uint8_t **out_label) { - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, - EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, (void *) out_label); + CBS label; + if (!EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, &label)) { + return -1; + } + if (CBS_len(&label) > INT_MAX) { + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_get0_rsa_oaep_label, ERR_R_OVERFLOW); + return -1; + } + *out_label = CBS_data(&label); + return (int)CBS_len(&label); } diff --git a/src/crypto/evp/p_rsa_asn1.c b/src/crypto/evp/p_rsa_asn1.c index f478d50..1e2d3f6 100644 --- a/src/crypto/evp/p_rsa_asn1.c +++ b/src/crypto/evp/p_rsa_asn1.c @@ -245,9 +245,7 @@ static int do_rsa_print(BIO *out, const RSA *rsa, int off, ret = 1; err: - if (m != NULL) { - OPENSSL_free(m); - } + OPENSSL_free(m); return ret; } @@ -394,12 +392,8 @@ static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, pss = rsa_pss_decode(sigalg, &maskHash); rv = rsa_pss_param_print(bp, pss, maskHash, indent); - if (pss) { - RSA_PSS_PARAMS_free(pss); - } - if (maskHash) { - X509_ALGOR_free(maskHash); - } + RSA_PSS_PARAMS_free(pss); + X509_ALGOR_free(maskHash); if (!rv) { return 0; } @@ -463,12 +457,11 @@ static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) { stmp = NULL; err: - if (stmp) - ASN1_STRING_free(stmp); - if (algtmp) - X509_ALGOR_free(algtmp); - if (*palg) + ASN1_STRING_free(stmp); + X509_ALGOR_free(algtmp); + if (*palg) { return 1; + } return 0; } @@ -518,8 +511,8 @@ static ASN1_STRING *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) { EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); int saltlen, rv = 0; - if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0 || - EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0 || + if (!EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) || + !EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) || !EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) { goto err; } @@ -560,12 +553,15 @@ static ASN1_STRING *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) { rv = 1; err: - if (pss) + if (pss) { RSA_PSS_PARAMS_free(pss); - if (rv) + } + if (rv) { return os; - if (os) + } + if (os) { ASN1_STRING_free(os); + } return NULL; } @@ -619,9 +615,9 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) { } if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey) || - EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0 || - EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0 || - EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) { + !EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) || + !EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) || + !EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md)) { goto err; } @@ -653,7 +649,7 @@ static evp_digest_sign_algorithm_result_t rsa_digest_sign_algorithm( EVP_MD_CTX *ctx, X509_ALGOR *sigalg) { int pad_mode; EVP_PKEY_CTX *pkctx = ctx->pctx; - if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) { + if (!EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode)) { return EVP_DIGEST_SIGN_ALGORITHM_ERROR; } if (pad_mode == RSA_PKCS1_PSS_PADDING) { diff --git a/src/crypto/evp/pbkdf_test.cc b/src/crypto/evp/pbkdf_test.cc new file mode 100644 index 0000000..ae2f405 --- /dev/null +++ b/src/crypto/evp/pbkdf_test.cc @@ -0,0 +1,179 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include <stdio.h> +#include <string.h> + +#include <openssl/bio.h> +#include <openssl/crypto.h> +#include <openssl/digest.h> +#include <openssl/err.h> +#include <openssl/evp.h> + + +// Prints out the data buffer as a sequence of hex bytes. +static void PrintDataHex(const void *data, size_t len) { + for (size_t i = 0; i < len; ++i) { + fprintf(stderr, "%02x", (int)((const uint8_t *)data)[i]); + } +} + +// Helper for testing that PBKDF2 derives the expected key from the given +// inputs. Returns 1 on success, 0 otherwise. +static bool TestPBKDF2(const void *password, size_t password_len, + const void *salt, size_t salt_len, unsigned iterations, + const EVP_MD *digest, size_t key_len, + const uint8_t *expected_key) { + uint8_t key[64]; + + if (key_len > sizeof(key)) { + fprintf(stderr, "Output buffer is not large enough.\n"); + return false; + } + + if (!PKCS5_PBKDF2_HMAC((const char *)password, password_len, + (const uint8_t *)salt, salt_len, iterations, digest, + key_len, key)) { + fprintf(stderr, "Call to PKCS5_PBKDF2_HMAC failed\n"); + ERR_print_errors_fp(stderr); + return false; + } + + if (memcmp(key, expected_key, key_len) != 0) { + fprintf(stderr, "Resulting key material does not match expectation\n"); + fprintf(stderr, "Expected:\n "); + PrintDataHex(expected_key, key_len); + fprintf(stderr, "\nActual:\n "); + PrintDataHex(key, key_len); + fprintf(stderr, "\n"); + return false; + } + + return true; +} + +// Tests deriving a key using an empty password (specified both as NULL and as +// non-NULL). Note that NULL has special meaning to HMAC initialization. +static bool TestEmptyPassword() { + const uint8_t kKey[] = {0xa3, 0x3d, 0xdd, 0xc3, 0x04, 0x78, 0x18, + 0x55, 0x15, 0x31, 0x1f, 0x87, 0x52, 0x89, + 0x5d, 0x36, 0xea, 0x43, 0x63, 0xa2}; + + if (!TestPBKDF2(NULL, 0, "salt", 4, 1, EVP_sha1(), sizeof(kKey), kKey) || + !TestPBKDF2("", 0, "salt", 4, 1, EVP_sha1(), sizeof(kKey), kKey)) { + return false; + } + + return true; +} + +// Tests deriving a key using an empty salt. Note that the expectation was +// generated using OpenSSL itself, and hence is not verified. +static bool TestEmptySalt() { + const uint8_t kKey[] = {0x8b, 0xc2, 0xf9, 0x16, 0x7a, 0x81, 0xcd, 0xcf, + 0xad, 0x12, 0x35, 0xcd, 0x90, 0x47, 0xf1, 0x13, + 0x62, 0x71, 0xc1, 0xf9, 0x78, 0xfc, 0xfc, 0xb3, + 0x5e, 0x22, 0xdb, 0xea, 0xfa, 0x46, 0x34, 0xf6}; + + if (!TestPBKDF2("password", 8, NULL, 0, 2, EVP_sha256(), sizeof(kKey), + kKey) || + !TestPBKDF2("password", 8, "", 0, 2, EVP_sha256(), sizeof(kKey), kKey)) { + return false; + } + + return true; +} + +// Exercises test vectors taken from https://tools.ietf.org/html/rfc6070. +// Note that each of these test vectors uses SHA-1 as the digest. +static bool TestRFC6070Vectors() { + const uint8_t kKey1[] = {0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, + 0x71, 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, + 0x12, 0x06, 0x2f, 0xe0, 0x37, 0xa6}; + const uint8_t kKey2[] = {0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, + 0x8c, 0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, + 0x41, 0xf0, 0xd8, 0xde, 0x89, 0x57}; + const uint8_t kKey3[] = {0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d, + 0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3}; + + if (!TestPBKDF2("password", 8, "salt", 4, 1, EVP_sha1(), sizeof(kKey1), + kKey1) || + !TestPBKDF2("password", 8, "salt", 4, 2, EVP_sha1(), sizeof(kKey2), + kKey2) || + !TestPBKDF2("pass\0word", 9, "sa\0lt", 5, 4096, EVP_sha1(), + sizeof(kKey3), kKey3)) { + return false; + } + + return true; +} + +// Tests key derivation using SHA-2 digests. +static bool TestSHA2() { + // This test was taken from: + // http://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors. + const uint8_t kKey1[] = {0xae, 0x4d, 0x0c, 0x95, 0xaf, 0x6b, 0x46, 0xd3, + 0x2d, 0x0a, 0xdf, 0xf9, 0x28, 0xf0, 0x6d, 0xd0, + 0x2a, 0x30, 0x3f, 0x8e, 0xf3, 0xc2, 0x51, 0xdf, + 0xd6, 0xe2, 0xd8, 0x5a, 0x95, 0x47, 0x4c, 0x43}; + + // This test was taken from: + // http://stackoverflow.com/questions/15593184/pbkdf2-hmac-sha-512-test-vectors. + const uint8_t kKey2[] = { + 0x8c, 0x05, 0x11, 0xf4, 0xc6, 0xe5, 0x97, 0xc6, 0xac, 0x63, 0x15, + 0xd8, 0xf0, 0x36, 0x2e, 0x22, 0x5f, 0x3c, 0x50, 0x14, 0x95, 0xba, + 0x23, 0xb8, 0x68, 0xc0, 0x05, 0x17, 0x4d, 0xc4, 0xee, 0x71, 0x11, + 0x5b, 0x59, 0xf9, 0xe6, 0x0c, 0xd9, 0x53, 0x2f, 0xa3, 0x3e, 0x0f, + 0x75, 0xae, 0xfe, 0x30, 0x22, 0x5c, 0x58, 0x3a, 0x18, 0x6c, 0xd8, + 0x2b, 0xd4, 0xda, 0xea, 0x97, 0x24, 0xa3, 0xd3, 0xb8}; + + if (!TestPBKDF2("password", 8, "salt", 4, 2, EVP_sha256(), sizeof(kKey1), + kKey1) || + !TestPBKDF2("passwordPASSWORDpassword", 24, + "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, 4096, + EVP_sha512(), sizeof(kKey2), kKey2)) { + return false; + } + + return true; +} + +int main(void) { + CRYPTO_library_init(); + ERR_load_crypto_strings(); + + if (!TestEmptyPassword()) { + fprintf(stderr, "TestEmptyPassword failed\n"); + return 1; + } + + if (!TestEmptySalt()) { + fprintf(stderr, "TestEmptySalt failed\n"); + return 1; + } + + if (!TestRFC6070Vectors()) { + fprintf(stderr, "TestRFC6070Vectors failed\n"); + return 1; + } + + if (!TestSHA2()) { + fprintf(stderr, "TestSHA2 failed\n"); + return 1; + } + + printf("PASS\n"); + ERR_free_strings(); + return 0; +} diff --git a/src/crypto/evp/sign.c b/src/crypto/evp/sign.c index 1faf7c6..ced86bd 100644 --- a/src/crypto/evp/sign.c +++ b/src/crypto/evp/sign.c @@ -92,9 +92,9 @@ int EVP_SignFinal(const EVP_MD_CTX *ctx, uint8_t *sig, EVP_MD_CTX_cleanup(&tmp_ctx); pkctx = EVP_PKEY_CTX_new(pkey, NULL); - if (!pkctx || EVP_PKEY_sign_init(pkctx) <= 0 || - EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0 || - EVP_PKEY_sign(pkctx, sig, &sig_len, m, m_len) <= 0) { + if (!pkctx || !EVP_PKEY_sign_init(pkctx) || + !EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) || + !EVP_PKEY_sign(pkctx, sig, &sig_len, m, m_len)) { goto out; } *out_sig_len = sig_len; @@ -138,8 +138,8 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, size_t sig_len, pkctx = EVP_PKEY_CTX_new(pkey, NULL); if (!pkctx || - EVP_PKEY_verify_init(pkctx) <= 0 || - EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0) { + !EVP_PKEY_verify_init(pkctx) || + !EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest)) { goto out; } ret = EVP_PKEY_verify(pkctx, sig, sig_len, m, m_len); |