diff options
Diffstat (limited to 'src/crypto/evp')
-rw-r--r-- | src/crypto/evp/CMakeLists.txt | 6 | ||||
-rw-r--r-- | src/crypto/evp/algorithm.c | 18 | ||||
-rw-r--r-- | src/crypto/evp/asn1.c (renamed from src/crypto/evp/evp_asn1.c) | 11 | ||||
-rw-r--r-- | src/crypto/evp/digestsign.c | 72 | ||||
-rw-r--r-- | src/crypto/evp/evp.c | 53 | ||||
-rw-r--r-- | src/crypto/evp/evp_ctx.c | 77 | ||||
-rw-r--r-- | src/crypto/evp/evp_extra_test.cc | 4 | ||||
-rw-r--r-- | src/crypto/evp/evp_test.cc | 64 | ||||
-rw-r--r-- | src/crypto/evp/evp_tests.txt | 5 | ||||
-rw-r--r-- | src/crypto/evp/internal.h | 69 | ||||
-rw-r--r-- | src/crypto/evp/p_dsa_asn1.c | 44 | ||||
-rw-r--r-- | src/crypto/evp/p_ec.c | 52 | ||||
-rw-r--r-- | src/crypto/evp/p_ec_asn1.c | 42 | ||||
-rw-r--r-- | src/crypto/evp/p_hmac.c | 223 | ||||
-rw-r--r-- | src/crypto/evp/p_hmac_asn1.c | 89 | ||||
-rw-r--r-- | src/crypto/evp/p_rsa.c | 49 | ||||
-rw-r--r-- | src/crypto/evp/p_rsa_asn1.c | 116 |
17 files changed, 728 insertions, 266 deletions
diff --git a/src/crypto/evp/CMakeLists.txt b/src/crypto/evp/CMakeLists.txt index 5d2e918..5769fa4 100644 --- a/src/crypto/evp/CMakeLists.txt +++ b/src/crypto/evp/CMakeLists.txt @@ -1,4 +1,4 @@ -include_directories(../../include) +include_directories(. .. ../../include) add_library( evp @@ -6,13 +6,15 @@ add_library( OBJECT algorithm.c + asn1.c digestsign.c evp.c - evp_asn1.c evp_ctx.c p_dsa_asn1.c p_ec.c p_ec_asn1.c + p_hmac.c + p_hmac_asn1.c p_rsa.c p_rsa_asn1.c pbkdf.c diff --git a/src/crypto/evp/algorithm.c b/src/crypto/evp/algorithm.c index 63bc77a..ea28dfa 100644 --- a/src/crypto/evp/algorithm.c +++ b/src/crypto/evp/algorithm.c @@ -74,7 +74,8 @@ int EVP_DigestSignAlgorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) { digest = EVP_MD_CTX_md(ctx); pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); if (!digest || !pkey) { - OPENSSL_PUT_ERROR(EVP, EVP_R_CONTEXT_NOT_INITIALISED); + OPENSSL_PUT_ERROR(EVP, EVP_DigestSignAlgorithm, + EVP_R_CONTEXT_NOT_INITIALISED); return 0; } @@ -96,7 +97,8 @@ int EVP_DigestSignAlgorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) { * that. */ if (!OBJ_find_sigid_by_algs(&sign_nid, EVP_MD_type(digest), pkey->ameth->pkey_id)) { - OPENSSL_PUT_ERROR(EVP, EVP_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); + OPENSSL_PUT_ERROR(EVP, EVP_DigestSignAlgorithm, + EVP_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); return 0; } @@ -120,21 +122,24 @@ int EVP_DigestVerifyInitFromAlgorithm(EVP_MD_CTX *ctx, /* Convert signature OID into digest and public key OIDs */ if (!OBJ_find_sigid_algs(OBJ_obj2nid(algor->algorithm), &digest_nid, &pkey_nid)) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_SIGNATURE_ALGORITHM); + OPENSSL_PUT_ERROR(EVP, EVP_DigestVerifyInitFromAlgorithm, + EVP_R_UNKNOWN_SIGNATURE_ALGORITHM); return 0; } /* Check public key OID matches public key type */ ameth = EVP_PKEY_asn1_find(NULL, pkey_nid); if (ameth == NULL || ameth->pkey_id != pkey->ameth->pkey_id) { - OPENSSL_PUT_ERROR(EVP, EVP_R_WRONG_PUBLIC_KEY_TYPE); + OPENSSL_PUT_ERROR(EVP, EVP_DigestVerifyInitFromAlgorithm, + EVP_R_WRONG_PUBLIC_KEY_TYPE); return 0; } /* NID_undef signals that there are custom parameters to set. */ if (digest_nid == NID_undef) { if (!pkey->ameth || !pkey->ameth->digest_verify_init_from_algorithm) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_SIGNATURE_ALGORITHM); + OPENSSL_PUT_ERROR(EVP, EVP_DigestVerifyInitFromAlgorithm, + EVP_R_UNKNOWN_SIGNATURE_ALGORITHM); return 0; } @@ -144,7 +149,8 @@ int EVP_DigestVerifyInitFromAlgorithm(EVP_MD_CTX *ctx, /* Otherwise, initialize with the digest from the OID. */ digest = EVP_get_digestbynid(digest_nid); if (digest == NULL) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); + OPENSSL_PUT_ERROR(EVP, EVP_DigestVerifyInitFromAlgorithm, + EVP_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); return 0; } diff --git a/src/crypto/evp/evp_asn1.c b/src/crypto/evp/asn1.c index 356c62b..3df9f52 100644 --- a/src/crypto/evp/evp_asn1.c +++ b/src/crypto/evp/asn1.c @@ -71,7 +71,7 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp, if (out == NULL || *out == NULL) { ret = EVP_PKEY_new(); if (ret == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_EVP_LIB); + OPENSSL_PUT_ERROR(EVP, d2i_PrivateKey, ERR_R_EVP_LIB); return NULL; } } else { @@ -79,7 +79,7 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp, } if (!EVP_PKEY_set_type(ret, type)) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE); + OPENSSL_PUT_ERROR(EVP, d2i_PrivateKey, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE); goto err; } @@ -94,7 +94,7 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp, ret = EVP_PKCS82PKEY(p8); PKCS8_PRIV_KEY_INFO_free(p8); } else { - OPENSSL_PUT_ERROR(EVP, ERR_R_ASN1_LIB); + OPENSSL_PUT_ERROR(EVP, d2i_PrivateKey, ERR_R_ASN1_LIB); goto err; } } @@ -134,7 +134,8 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) { sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); if (!p8) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + OPENSSL_PUT_ERROR(EVP, d2i_AutoPrivateKey, + EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); return NULL; } ret = EVP_PKCS82PKEY(p8); @@ -160,7 +161,7 @@ int i2d_PublicKey(EVP_PKEY *key, uint8_t **outp) { case EVP_PKEY_EC: return i2o_ECPublicKey(key->pkey.ec, outp); default: - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + OPENSSL_PUT_ERROR(EVP, i2d_PublicKey, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); return -1; } } diff --git a/src/crypto/evp/digestsign.c b/src/crypto/evp/digestsign.c index ccb4de4..c163d40 100644 --- a/src/crypto/evp/digestsign.c +++ b/src/crypto/evp/digestsign.c @@ -62,9 +62,17 @@ #include "../digest/internal.h" +/* 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) { + 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 = { EVP_PKEY_CTX_free, EVP_PKEY_CTX_dup, + md_begin_digest, }; static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, @@ -83,16 +91,26 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, } if (type == NULL) { - OPENSSL_PUT_ERROR(EVP, EVP_R_NO_DEFAULT_DIGEST); + OPENSSL_PUT_ERROR(EVP, do_sigver_init, EVP_R_NO_DEFAULT_DIGEST); return 0; } if (is_verify) { - if (!EVP_PKEY_verify_init(ctx->pctx)) { + if (ctx->pctx->pmeth->verifyctx_init) { + 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)) { return 0; } } else { - if (!EVP_PKEY_sign_init(ctx->pctx)) { + if (ctx->pctx->pmeth->signctx_init) { + 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)) { return 0; } } @@ -128,37 +146,59 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { int EVP_DigestSignFinal(EVP_MD_CTX *ctx, uint8_t *out_sig, size_t *out_sig_len) { + int r = 0; + const int has_signctx = ctx->pctx->pmeth->signctx != NULL; + if (out_sig) { EVP_MD_CTX tmp_ctx; - int ret; uint8_t md[EVP_MAX_MD_SIZE]; unsigned int mdlen; EVP_MD_CTX_init(&tmp_ctx); - ret = EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) && - EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen) && - EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, md, mdlen); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) { + return 0; + } + if (has_signctx) { + 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); - - return ret; + return r; } else { - size_t s = EVP_MD_size(ctx->digest); - return EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, NULL, s); + if (has_signctx) { + return ctx->pctx->pmeth->signctx(ctx->pctx, out_sig, out_sig_len, ctx); + } else { + size_t s = EVP_MD_size(ctx->digest); + return EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, NULL, s); + } } } int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, size_t sig_len) { EVP_MD_CTX tmp_ctx; - int ret; uint8_t md[EVP_MAX_MD_SIZE]; + int r; unsigned int mdlen; EVP_MD_CTX_init(&tmp_ctx); - ret = EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) && - EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen) && - EVP_PKEY_verify(ctx->pctx, sig, sig_len, md, mdlen); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) { + return 0; + } + 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); - return ret; + return r; } diff --git a/src/crypto/evp/evp.c b/src/crypto/evp/evp.c index 5822379..0ad5c27 100644 --- a/src/crypto/evp/evp.c +++ b/src/crypto/evp/evp.c @@ -75,6 +75,7 @@ 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; EVP_PKEY *EVP_PKEY_new(void) { @@ -82,7 +83,7 @@ EVP_PKEY *EVP_PKEY_new(void) { ret = OPENSSL_malloc(sizeof(EVP_PKEY)); if (ret == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_new, ERR_R_MALLOC_FAILURE); return NULL; } @@ -158,12 +159,12 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { if (to->type != from->type) { - OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_copy_parameters, EVP_R_DIFFERENT_KEY_TYPES); goto err; } if (EVP_PKEY_missing_parameters(from)) { - OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_copy_parameters, EVP_R_MISSING_PARAMETERS); goto err; } @@ -206,6 +207,8 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pengine, int nid) { case EVP_PKEY_RSA: case EVP_PKEY_RSA2: return &rsa_asn1_meth; + case EVP_PKEY_HMAC: + return &hmac_asn1_meth; case EVP_PKEY_EC: return &ec_asn1_meth; case EVP_PKEY_DSA: @@ -223,6 +226,32 @@ int EVP_PKEY_type(int nid) { return meth->pkey_id; } +EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, const uint8_t *mac_key, + size_t mac_key_len) { + EVP_PKEY_CTX *mac_ctx = NULL; + EVP_PKEY *ret = NULL; + + mac_ctx = EVP_PKEY_CTX_new_id(type, e); + if (!mac_ctx) { + return NULL; + } + + 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) { + EVP_PKEY_CTX_free(mac_ctx); + } + return ret; +} + int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) { if (EVP_PKEY_assign_RSA(pkey, key)) { RSA_up_ref(key); @@ -237,7 +266,7 @@ int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key) { RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) { if (pkey->type != EVP_PKEY_RSA) { - OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_RSA_KEY); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_get1_RSA, EVP_R_EXPECTING_AN_RSA_KEY); return NULL; } RSA_up_ref(pkey->pkey.rsa); @@ -258,7 +287,7 @@ int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) { DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) { if (pkey->type != EVP_PKEY_DSA) { - OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DSA_KEY); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_get1_DSA, EVP_R_EXPECTING_A_DSA_KEY); return NULL; } DSA_up_ref(pkey->pkey.dsa); @@ -279,7 +308,7 @@ int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) { if (pkey->type != EVP_PKEY_EC) { - OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_EC_KEY_KEY); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_get1_EC_KEY, EVP_R_EXPECTING_AN_EC_KEY_KEY); return NULL; } EC_KEY_up_ref(pkey->pkey.ec); @@ -300,7 +329,7 @@ int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key) { DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) { if (pkey->type != EVP_PKEY_DH) { - OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DH_KEY); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_get1_DH, EVP_R_EXPECTING_A_DH_KEY); return NULL; } DH_up_ref(pkey->pkey.dh); @@ -320,10 +349,10 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pengine, size_t len) { if (len == 3 && memcmp(name, "RSA", 3) == 0) { return &rsa_asn1_meth; + } else if (len == 4 && memcmp(name, "HMAC", 4) == 0) { + return &hmac_asn1_meth; } if (len == 2 && memcmp(name, "EC", 2) == 0) { return &ec_asn1_meth; - } else if (len == 3 && memcmp(name, "DSA", 3) == 0) { - return &dsa_asn1_meth; } return NULL; } @@ -337,7 +366,7 @@ int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) { ameth = EVP_PKEY_asn1_find(NULL, type); if (ameth == NULL) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_set_type, EVP_R_UNSUPPORTED_ALGORITHM); ERR_add_error_dataf("algorithm %d (%s)", type, OBJ_nid2sn(type)); return 0; } @@ -407,6 +436,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 OpenSSL_add_all_ciphers(void) {} diff --git a/src/crypto/evp/evp_ctx.c b/src/crypto/evp/evp_ctx.c index a8e71fe..9f42274 100644 --- a/src/crypto/evp/evp_ctx.c +++ b/src/crypto/evp/evp_ctx.c @@ -67,10 +67,12 @@ extern const EVP_PKEY_METHOD rsa_pkey_meth; +extern const EVP_PKEY_METHOD hmac_pkey_meth; extern const EVP_PKEY_METHOD ec_pkey_meth; static const EVP_PKEY_METHOD *const evp_methods[] = { &rsa_pkey_meth, + &hmac_pkey_meth, &ec_pkey_meth, }; @@ -100,7 +102,7 @@ static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) { pmeth = evp_pkey_meth_find(id); if (pmeth == NULL) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + OPENSSL_PUT_ERROR(EVP, evp_pkey_ctx_new, EVP_R_UNSUPPORTED_ALGORITHM); const char *name = OBJ_nid2sn(id); ERR_add_error_dataf("algorithm %d (%s)", id, name); return NULL; @@ -108,7 +110,7 @@ static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) { ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); if (!ret) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(EVP, evp_pkey_ctx_new, ERR_R_MALLOC_FAILURE); return NULL; } memset(ret, 0, sizeof(EVP_PKEY_CTX)); @@ -190,7 +192,7 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx) { err: EVP_PKEY_CTX_free(rctx); - OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_dup, ERR_LIB_EVP); return NULL; } @@ -205,7 +207,7 @@ 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) { if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) { - OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_ctrl, EVP_R_COMMAND_NOT_SUPPORTED); return 0; } if (keytype != -1 && ctx->pmeth->pkey_id != keytype) { @@ -213,12 +215,12 @@ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, } if (ctx->operation == EVP_PKEY_OP_UNDEFINED) { - OPENSSL_PUT_ERROR(EVP, EVP_R_NO_OPERATION_SET); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_ctrl, EVP_R_NO_OPERATION_SET); return 0; } if (optype != -1 && !(ctx->operation & optype)) { - OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_OPERATION); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_ctrl, EVP_R_INVALID_OPERATION); return 0; } @@ -227,7 +229,8 @@ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) { if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { - OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_sign_init, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; } @@ -247,11 +250,12 @@ int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) { int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *sig_len, const uint8_t *data, size_t data_len) { if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { - OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_sign, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; } if (ctx->operation != EVP_PKEY_OP_SIGN) { - OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_sign, EVP_R_OPERATON_NOT_INITIALIZED); return 0; } return ctx->pmeth->sign(ctx, sig, sig_len, data, data_len); @@ -259,7 +263,8 @@ int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *sig_len, int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) { if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { - OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_verify_init, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; } ctx->operation = EVP_PKEY_OP_VERIFY; @@ -277,11 +282,12 @@ int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) { int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t sig_len, const uint8_t *data, size_t data_len) { if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { - OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_verify, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; } if (ctx->operation != EVP_PKEY_OP_VERIFY) { - OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_verify, EVP_R_OPERATON_NOT_INITIALIZED); return 0; } return ctx->pmeth->verify(ctx, sig, sig_len, data, data_len); @@ -289,7 +295,8 @@ int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t sig_len, int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) { if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { - OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_encrypt_init, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; } ctx->operation = EVP_PKEY_OP_ENCRYPT; @@ -306,11 +313,12 @@ int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) { int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, const uint8_t *in, size_t inlen) { if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { - OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_encrypt, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; } if (ctx->operation != EVP_PKEY_OP_ENCRYPT) { - OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_encrypt, EVP_R_OPERATON_NOT_INITIALIZED); return 0; } return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen); @@ -318,7 +326,8 @@ int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) { if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { - OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_decrypt_init, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; } ctx->operation = EVP_PKEY_OP_DECRYPT; @@ -335,11 +344,12 @@ int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) { int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, const uint8_t *in, size_t inlen) { if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { - OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_decrypt, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; } if (ctx->operation != EVP_PKEY_OP_DECRYPT) { - OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_decrypt, EVP_R_OPERATON_NOT_INITIALIZED); return 0; } return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); @@ -347,7 +357,8 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) { if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { - OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_init, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; } ctx->operation = EVP_PKEY_OP_DERIVE; @@ -366,13 +377,15 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) { if (!ctx || !ctx->pmeth || !(ctx->pmeth->derive || ctx->pmeth->encrypt || ctx->pmeth->decrypt) || !ctx->pmeth->ctrl) { - OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_set_peer, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; } if (ctx->operation != EVP_PKEY_OP_DERIVE && ctx->operation != EVP_PKEY_OP_ENCRYPT && ctx->operation != EVP_PKEY_OP_DECRYPT) { - OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_set_peer, + EVP_R_OPERATON_NOT_INITIALIZED); return 0; } @@ -387,12 +400,12 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) { } if (!ctx->pkey) { - OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_set_peer, EVP_R_NO_KEY_SET); return 0; } if (ctx->pkey->type != peer->type) { - OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_set_peer, EVP_R_DIFFERENT_KEY_TYPES); return 0; } @@ -403,7 +416,8 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) { * -2 is OK for us here, as well as 1, so we can check for 0 only. */ if (!EVP_PKEY_missing_parameters(peer) && !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) { - OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_PARAMETERS); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_set_peer, + EVP_R_DIFFERENT_PARAMETERS); return 0; } @@ -423,11 +437,12 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) { int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *out_key_len) { if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { - OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; } if (ctx->operation != EVP_PKEY_OP_DERIVE) { - OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive, EVP_R_OPERATON_NOT_INITIALIZED); return 0; } return ctx->pmeth->derive(ctx, key, out_key_len); @@ -435,7 +450,8 @@ int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *out_key_len) { int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) { if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { - OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_keygen_init, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; } ctx->operation = EVP_PKEY_OP_KEYGEN; @@ -451,11 +467,12 @@ int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) { int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) { if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { - OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_keygen, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; } if (ctx->operation != EVP_PKEY_OP_KEYGEN) { - OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_keygen, EVP_R_OPERATON_NOT_INITIALIZED); return 0; } @@ -466,7 +483,7 @@ int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) { if (!*ppkey) { *ppkey = EVP_PKEY_new(); if (!*ppkey) { - OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_keygen, ERR_LIB_EVP); return 0; } } diff --git a/src/crypto/evp/evp_extra_test.cc b/src/crypto/evp/evp_extra_test.cc index 9c955fa..674547d 100644 --- a/src/crypto/evp/evp_extra_test.cc +++ b/src/crypto/evp/evp_extra_test.cc @@ -322,8 +322,8 @@ static const uint8_t kExampleBadECKeyDER[] = { }; static ScopedEVP_PKEY LoadExampleRSAKey() { - ScopedRSA rsa(RSA_private_key_from_bytes(kExampleRSAKeyDER, - sizeof(kExampleRSAKeyDER))); + const uint8_t *derp = kExampleRSAKeyDER; + ScopedRSA rsa(d2i_RSAPrivateKey(nullptr, &derp, sizeof(kExampleRSAKeyDER))); if (!rsa) { return nullptr; } diff --git a/src/crypto/evp/evp_test.cc b/src/crypto/evp/evp_test.cc index c7ac908..239f868 100644 --- a/src/crypto/evp/evp_test.cc +++ b/src/crypto/evp/evp_test.cc @@ -56,19 +56,10 @@ #include <stdlib.h> #include <string.h> -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable: 4702) -#endif - #include <map> #include <string> #include <vector> -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - #include <openssl/bio.h> #include <openssl/crypto.h> #include <openssl/digest.h> @@ -81,10 +72,11 @@ #include "../test/stl_compat.h" -// evp_test dispatches between multiple test types. 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. +// 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") { @@ -128,10 +120,54 @@ static bool ImportPrivateKey(FileTest *t, KeyMap *key_map) { 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); @@ -183,7 +219,7 @@ static bool TestEVP(FileTest *t, void *arg) { 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. - OPENSSL_PUT_ERROR(USER, ERR_R_EVP_LIB); + ERR_put_error(ERR_LIB_USER, 0, ERR_R_EVP_LIB, __FILE__, __LINE__); return false; } return true; diff --git a/src/crypto/evp/evp_tests.txt b/src/crypto/evp/evp_tests.txt index 97ddaa0..cccfa4f 100644 --- a/src/crypto/evp/evp_tests.txt +++ b/src/crypto/evp/evp_tests.txt @@ -163,11 +163,12 @@ Digest = SHA1 Input = "0123456789ABCDEF1234" Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec800 # This operation fails without an error code, so ERR_R_EVP_LIB is surfaced. -Error = BAD_SIGNATURE +Error = public key routines # BER signature Verify = P-256 Digest = SHA1 Input = "0123456789ABCDEF1234" Output = 3080022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec80000 -Error = BAD_SIGNATURE +# 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 60881e3..08a7bfb 100644 --- a/src/crypto/evp/internal.h +++ b/src/crypto/evp/internal.h @@ -89,7 +89,8 @@ struct evp_pkey_asn1_method_st { int pkey_base_id; unsigned long pkey_flags; - const char *pem_str; + char *pem_str; + char *info; int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub); int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk); @@ -114,8 +115,8 @@ struct evp_pkey_asn1_method_st { int (*pkey_size)(const EVP_PKEY *pk); int (*pkey_bits)(const EVP_PKEY *pk); - int (*param_decode)(EVP_PKEY *pkey, const uint8_t **pder, int derlen); - int (*param_encode)(const EVP_PKEY *pkey, uint8_t **pder); + int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder, int derlen); + int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder); int (*param_missing)(const EVP_PKEY *pk); int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from); int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b); @@ -129,9 +130,9 @@ struct evp_pkey_asn1_method_st { /* Legacy functions for old PEM */ - int (*old_priv_decode)(EVP_PKEY *pkey, const uint8_t **pder, + int (*old_priv_decode)(EVP_PKEY *pkey, const unsigned char **pder, int derlen); - int (*old_priv_encode)(const EVP_PKEY *pkey, uint8_t **pder); + int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder); /* Converting parameters to/from AlgorithmIdentifier (X509_ALGOR). */ int (*digest_verify_init_from_algorithm)(EVP_MD_CTX *ctx, @@ -152,12 +153,15 @@ typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx); #define EVP_PKEY_OP_SIGN (1 << 3) #define EVP_PKEY_OP_VERIFY (1 << 4) #define EVP_PKEY_OP_VERIFYRECOVER (1 << 5) -#define EVP_PKEY_OP_ENCRYPT (1 << 6) -#define EVP_PKEY_OP_DECRYPT (1 << 7) -#define EVP_PKEY_OP_DERIVE (1 << 8) +#define EVP_PKEY_OP_SIGNCTX (1 << 6) +#define EVP_PKEY_OP_VERIFYCTX (1 << 7) +#define EVP_PKEY_OP_ENCRYPT (1 << 8) +#define EVP_PKEY_OP_DECRYPT (1 << 9) +#define EVP_PKEY_OP_DERIVE (1 << 10) #define EVP_PKEY_OP_TYPE_SIG \ - (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER) + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER | \ + EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX) #define EVP_PKEY_OP_TYPE_CRYPT (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT) @@ -177,8 +181,13 @@ typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx); OPENSSL_EXPORT int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2); -#define EVP_PKEY_CTRL_MD 1 -#define EVP_PKEY_CTRL_GET_MD 2 +/* 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. @@ -189,12 +198,21 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, * (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 3 +#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) @@ -242,25 +260,34 @@ struct evp_pkey_method_st { int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); int (*sign_init)(EVP_PKEY_CTX *ctx); - int (*sign)(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, - const uint8_t *tbs, size_t tbslen); + int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); int (*verify_init)(EVP_PKEY_CTX *ctx); - int (*verify)(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, - const uint8_t *tbs, size_t tbslen); + int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen); + + int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); + int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + EVP_MD_CTX *mctx); + + int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); + int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen, + EVP_MD_CTX *mctx); int (*encrypt_init)(EVP_PKEY_CTX *ctx); - int (*encrypt)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, - const uint8_t *in, size_t inlen); + int (*encrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); int (*decrypt_init)(EVP_PKEY_CTX *ctx); - int (*decrypt)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, - const uint8_t *in, size_t inlen); + int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); int (*derive_init)(EVP_PKEY_CTX *ctx); - int (*derive)(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *keylen); + int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2); + int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value); } /* EVP_PKEY_METHOD */; diff --git a/src/crypto/evp/p_dsa_asn1.c b/src/crypto/evp/p_dsa_asn1.c index 4790cf6..826d4e4 100644 --- a/src/crypto/evp/p_dsa_asn1.c +++ b/src/crypto/evp/p_dsa_asn1.c @@ -91,29 +91,29 @@ static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { dsa = d2i_DSAparams(NULL, &pm, pmlen); if (dsa == NULL) { - OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + 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, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, ERR_R_MALLOC_FAILURE); goto err; } } else { - OPENSSL_PUT_ERROR(EVP, EVP_R_PARAMETER_ENCODING_ERROR); + 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, EVP_R_DECODE_ERROR); + 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, EVP_R_BN_DECODE_ERROR); + OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, EVP_R_BN_DECODE_ERROR); goto err; } @@ -140,12 +140,12 @@ static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { if (dsa->p && dsa->q && dsa->g) { pval = ASN1_STRING_new(); if (!pval) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(EVP, dsa_pub_encode, ERR_R_MALLOC_FAILURE); goto err; } pval->length = i2d_DSAparams(dsa, &pval->data); if (pval->length <= 0) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(EVP, dsa_pub_encode, ERR_R_MALLOC_FAILURE); goto err; } ptype = V_ASN1_SEQUENCE; @@ -155,7 +155,7 @@ static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { penclen = i2d_DSAPublicKey(dsa, &penc); if (penclen <= 0) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(EVP, dsa_pub_encode, ERR_R_MALLOC_FAILURE); goto err; } @@ -252,23 +252,23 @@ static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { /* 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, ERR_LIB_BN); + 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, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, ERR_R_MALLOC_FAILURE); goto dsaerr; } ctx = BN_CTX_new(); if (ctx == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + 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, ERR_LIB_BN); + OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, ERR_LIB_BN); goto dsaerr; } @@ -280,7 +280,7 @@ static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { return 1; decerr: - OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, EVP_R_DECODE_ERROR); dsaerr: BN_CTX_free(ctx); @@ -297,19 +297,19 @@ static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { int dplen; if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key) { - OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); + OPENSSL_PUT_ERROR(EVP, dsa_priv_encode, EVP_R_MISSING_PARAMETERS); goto err; } params = ASN1_STRING_new(); if (!params) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + 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, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(EVP, dsa_priv_encode, ERR_R_MALLOC_FAILURE); goto err; } params->type = V_ASN1_SEQUENCE; @@ -318,14 +318,13 @@ static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL); if (!prkey) { - OPENSSL_PUT_ERROR(EVP, ERR_LIB_BN); + OPENSSL_PUT_ERROR(EVP, dsa_priv_encode, ERR_LIB_BN); goto err; } dplen = i2d_ASN1_INTEGER(prkey, &dp); ASN1_INTEGER_free(prkey); - prkey = NULL; if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_dsa), 0, V_ASN1_SEQUENCE, params, dp, dplen)) { @@ -438,7 +437,7 @@ static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) { m = (uint8_t *)OPENSSL_malloc(buf_len + 10); if (m == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(EVP, do_dsa_print, ERR_R_MALLOC_FAILURE); goto err; } @@ -467,7 +466,7 @@ 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, ERR_R_DSA_LIB); + OPENSSL_PUT_ERROR(EVP, dsa_param_decode, ERR_R_DSA_LIB); return 0; } EVP_PKEY_assign_DSA(pkey, dsa); @@ -498,7 +497,7 @@ static int old_dsa_priv_decode(EVP_PKEY *pkey, const uint8_t **pder, DSA *dsa; dsa = d2i_DSAPrivateKey(NULL, pder, derlen); if (dsa == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_DSA_LIB); + OPENSSL_PUT_ERROR(EVP, old_dsa_priv_decode, ERR_R_DSA_LIB); return 0; } EVP_PKEY_assign_DSA(pkey, dsa); @@ -532,7 +531,7 @@ static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, update_buflen(dsa_sig->s, &buf_len); m = OPENSSL_malloc(buf_len + 10); if (m == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(EVP, dsa_sig_print, ERR_R_MALLOC_FAILURE); goto err; } @@ -555,6 +554,7 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = { 0, "DSA", + "OpenSSL DSA method", dsa_pub_decode, dsa_pub_encode, diff --git a/src/crypto/evp/p_ec.c b/src/crypto/evp/p_ec.c index 77f213d..73c00d8 100644 --- a/src/crypto/evp/p_ec.c +++ b/src/crypto/evp/p_ec.c @@ -125,18 +125,25 @@ static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) { static int pkey_ec_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, const uint8_t *tbs, size_t tbslen) { + int type; unsigned int sltmp; + EC_PKEY_CTX *dctx = ctx->data; EC_KEY *ec = ctx->pkey->pkey.ec; if (!sig) { *siglen = ECDSA_size(ec); return 1; } else if (*siglen < (size_t)ECDSA_size(ec)) { - OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + OPENSSL_PUT_ERROR(EVP, pkey_ec_sign, EVP_R_BUFFER_TOO_SMALL); return 0; } - if (!ECDSA_sign(0, tbs, tbslen, sig, &sltmp, ec)) { + type = NID_sha1; + if (dctx->md) { + type = EVP_MD_type(dctx->md); + } + + if (!ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec)) { return 0; } *siglen = (size_t)sltmp; @@ -145,7 +152,16 @@ static int pkey_ec_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, static int pkey_ec_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, const uint8_t *tbs, size_t tbslen) { - return ECDSA_verify(0, tbs, tbslen, sig, siglen, ctx->pkey->pkey.ec); + int type; + EC_PKEY_CTX *dctx = ctx->data; + EC_KEY *ec = ctx->pkey->pkey.ec; + + type = NID_sha1; + if (dctx->md) { + type = EVP_MD_type(dctx->md); + } + + return ECDSA_verify(type, tbs, tbslen, sig, siglen, ec); } static int pkey_ec_derive(EVP_PKEY_CTX *ctx, uint8_t *key, @@ -156,7 +172,7 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, uint8_t *key, EC_KEY *eckey; if (!ctx->pkey || !ctx->peerkey) { - OPENSSL_PUT_ERROR(EVP, EVP_R_KEYS_NOT_SET); + OPENSSL_PUT_ERROR(EVP, pkey_ec_derive, EVP_R_KEYS_NOT_SET); return 0; } @@ -191,7 +207,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: group = EC_GROUP_new_by_curve_name(p1); if (group == NULL) { - OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_CURVE); + OPENSSL_PUT_ERROR(EVP, pkey_ec_ctrl, EVP_R_INVALID_CURVE); return 0; } EC_GROUP_free(dctx->gen_group); @@ -205,7 +221,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { EVP_MD_type((const EVP_MD *)p2) != NID_sha256 && EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && EVP_MD_type((const EVP_MD *)p2) != NID_sha512) { - OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_DIGEST_TYPE); + OPENSSL_PUT_ERROR(EVP, pkey_ec_ctrl, EVP_R_INVALID_DIGEST_TYPE); return 0; } dctx->md = p2; @@ -216,11 +232,12 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { return 1; case EVP_PKEY_CTRL_PEER_KEY: - /* Default behaviour is OK */ + /* Default behaviour is OK */ + case EVP_PKEY_CTRL_DIGESTINIT: return 1; default: - OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); + OPENSSL_PUT_ERROR(EVP, pkey_ec_ctrl, EVP_R_COMMAND_NOT_SUPPORTED); return 0; } } @@ -231,7 +248,7 @@ static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { int ret = 0; if (dctx->gen_group == NULL) { - OPENSSL_PUT_ERROR(EVP, EVP_R_NO_PARAMETERS_SET); + OPENSSL_PUT_ERROR(EVP, pkey_ec_paramgen, EVP_R_NO_PARAMETERS_SET); return 0; } ec = EC_KEY_new(); @@ -251,7 +268,7 @@ static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { EC_KEY *ec = NULL; EC_PKEY_CTX *dctx = ctx->data; if (ctx->pkey == NULL && dctx->gen_group == NULL) { - OPENSSL_PUT_ERROR(EVP, EVP_R_NO_PARAMETERS_SET); + OPENSSL_PUT_ERROR(EVP, pkey_ec_keygen, EVP_R_NO_PARAMETERS_SET); return 0; } ec = EC_KEY_new(); @@ -273,11 +290,12 @@ static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { } const EVP_PKEY_METHOD ec_pkey_meth = { - EVP_PKEY_EC, 0 /* flags */, pkey_ec_init, - pkey_ec_copy, pkey_ec_cleanup, 0 /* paramgen_init */, - pkey_ec_paramgen, 0 /* keygen_init */, pkey_ec_keygen, - 0 /* sign_init */, pkey_ec_sign, 0 /* verify_init */, - pkey_ec_verify, 0 /* encrypt_init */, 0 /* encrypt */, - 0 /* decrypt_init */, 0 /* decrypt */, 0 /* derive_init */, - pkey_ec_derive, pkey_ec_ctrl, + EVP_PKEY_EC, 0 /* flags */, pkey_ec_init, + pkey_ec_copy, pkey_ec_cleanup, 0 /* paramgen_init */, + pkey_ec_paramgen, 0 /* keygen_init */, pkey_ec_keygen, + 0 /* sign_init */, pkey_ec_sign, 0 /* verify_init */, + pkey_ec_verify, 0 /* signctx_init */, 0 /* signctx */, + 0 /* verifyctx_init */, 0 /* verifyctx */, 0 /* encrypt_init */, + 0 /* encrypt */, 0 /* decrypt_init */, 0 /* decrypt */, + 0 /* derive_init */, pkey_ec_derive, pkey_ec_ctrl, }; diff --git a/src/crypto/evp/p_ec_asn1.c b/src/crypto/evp/p_ec_asn1.c index 9867947..fbbf4e7 100644 --- a/src/crypto/evp/p_ec_asn1.c +++ b/src/crypto/evp/p_ec_asn1.c @@ -71,13 +71,13 @@ static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) { int nid; if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) { - OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); + OPENSSL_PUT_ERROR(EVP, eckey_param2type, EVP_R_MISSING_PARAMETERS); return 0; } nid = EC_GROUP_get_curve_name(group); if (nid == NID_undef) { - OPENSSL_PUT_ERROR(EVP, EVP_R_NO_NID_FOR_CURVE); + OPENSSL_PUT_ERROR(EVP, eckey_param2type, EVP_R_NO_NID_FOR_CURVE); return 0; } @@ -94,7 +94,7 @@ static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { int penclen; if (!eckey_param2type(&ptype, &pval, ec_key)) { - OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB); + OPENSSL_PUT_ERROR(EVP, eckey_pub_encode, ERR_R_EC_LIB); return 0; } penclen = i2o_ECPublicKey(ec_key, NULL); @@ -137,7 +137,7 @@ static EC_KEY *eckey_type2param(int ptype, void *pval) { eckey = d2i_ECParameters(NULL, &pm, pmlen); if (eckey == NULL) { - OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(EVP, eckey_type2param, EVP_R_DECODE_ERROR); goto err; } } else if (ptype == V_ASN1_OBJECT) { @@ -150,7 +150,7 @@ static EC_KEY *eckey_type2param(int ptype, void *pval) { goto err; } } else { - OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(EVP, eckey_type2param, EVP_R_DECODE_ERROR); goto err; } @@ -177,13 +177,13 @@ static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { eckey = eckey_type2param(ptype, pval); if (!eckey) { - OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB); + OPENSSL_PUT_ERROR(EVP, eckey_pub_decode, ERR_R_EC_LIB); return 0; } /* We have parameters now set public key */ if (!o2i_ECPublicKey(&eckey, &p, pklen)) { - OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(EVP, eckey_pub_decode, EVP_R_DECODE_ERROR); goto err; } @@ -232,7 +232,7 @@ static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { /* We have parameters now set private key */ if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { - OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, EVP_R_DECODE_ERROR); goto ecerr; } @@ -246,23 +246,23 @@ static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { group = EC_KEY_get0_group(eckey); pub_key = EC_POINT_new(group); if (pub_key == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB); + OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB); goto ecliberr; } if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { EC_POINT_free(pub_key); - OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB); + OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB); goto ecliberr; } priv_key = EC_KEY_get0_private_key(eckey); if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) { EC_POINT_free(pub_key); - OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB); + OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB); goto ecliberr; } if (EC_KEY_set_public_key(eckey, pub_key) == 0) { EC_POINT_free(pub_key); - OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB); + OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB); goto ecliberr; } EC_POINT_free(pub_key); @@ -272,7 +272,7 @@ static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { return 1; ecliberr: - OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB); + OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB); ecerr: if (eckey) { EC_KEY_free(eckey); @@ -290,7 +290,7 @@ static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { ec_key = pkey->pkey.ec; if (!eckey_param2type(&ptype, &pval, ec_key)) { - OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(EVP, eckey_priv_encode, EVP_R_DECODE_ERROR); return 0; } @@ -304,20 +304,20 @@ static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { eplen = i2d_ECPrivateKey(ec_key, NULL); if (!eplen) { EC_KEY_set_enc_flags(ec_key, old_flags); - OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB); + OPENSSL_PUT_ERROR(EVP, eckey_priv_encode, ERR_R_EC_LIB); return 0; } ep = (uint8_t *)OPENSSL_malloc(eplen); if (!ep) { EC_KEY_set_enc_flags(ec_key, old_flags); - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(EVP, eckey_priv_encode, ERR_R_MALLOC_FAILURE); return 0; } p = ep; if (!i2d_ECPrivateKey(ec_key, &p)) { EC_KEY_set_enc_flags(ec_key, old_flags); OPENSSL_free(ep); - OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB); + OPENSSL_PUT_ERROR(EVP, eckey_priv_encode, ERR_R_EC_LIB); return 0; } /* restore old encoding flags */ @@ -325,7 +325,6 @@ static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0, ptype, pval, ep, eplen)) { - OPENSSL_free(ep); return 0; } @@ -479,7 +478,7 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) { err: if (!ret) { - OPENSSL_PUT_ERROR(EVP, reason); + OPENSSL_PUT_ERROR(EVP, do_EC_KEY_print, reason); } OPENSSL_free(pub_key_bytes); BN_free(order); @@ -492,7 +491,7 @@ static int eckey_param_decode(EVP_PKEY *pkey, const uint8_t **pder, int derlen) { EC_KEY *eckey; if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) { - OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB); + OPENSSL_PUT_ERROR(EVP, eckey_param_decode, ERR_R_EC_LIB); return 0; } EVP_PKEY_assign_EC_KEY(pkey, eckey); @@ -527,7 +526,7 @@ static int old_ec_priv_decode(EVP_PKEY *pkey, const uint8_t **pder, int derlen) { EC_KEY *ec; if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) { - OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(EVP, old_ec_priv_decode, EVP_R_DECODE_ERROR); return 0; } EVP_PKEY_assign_EC_KEY(pkey, ec); @@ -543,6 +542,7 @@ const EVP_PKEY_ASN1_METHOD ec_asn1_meth = { EVP_PKEY_EC, 0, "EC", + "OpenSSL EC algorithm", eckey_pub_decode, eckey_pub_encode, diff --git a/src/crypto/evp/p_hmac.c b/src/crypto/evp/p_hmac.c new file mode 100644 index 0000000..7d3254a --- /dev/null +++ b/src/crypto/evp/p_hmac.c @@ -0,0 +1,223 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2007. + */ +/* ==================================================================== + * Copyright (c) 2007 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 <string.h> + +#include <openssl/asn1.h> +#include <openssl/err.h> +#include <openssl/hmac.h> +#include <openssl/mem.h> +#include <openssl/obj.h> + +#include "internal.h" +#include "../digest/internal.h" + + +typedef struct { + const EVP_MD *md; /* MD for HMAC use */ + ASN1_OCTET_STRING ktmp; /* Temp storage for key */ + HMAC_CTX ctx; +} HMAC_PKEY_CTX; + +static int pkey_hmac_init(EVP_PKEY_CTX *ctx) { + HMAC_PKEY_CTX *hctx; + hctx = OPENSSL_malloc(sizeof(HMAC_PKEY_CTX)); + if (!hctx) { + return 0; + } + memset(hctx, 0, sizeof(HMAC_PKEY_CTX)); + hctx->ktmp.type = V_ASN1_OCTET_STRING; + HMAC_CTX_init(&hctx->ctx); + + ctx->data = hctx; + + return 1; +} + +static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { + HMAC_PKEY_CTX *sctx, *dctx; + if (!pkey_hmac_init(dst)) { + return 0; + } + sctx = src->data; + dctx = dst->data; + dctx->md = sctx->md; + HMAC_CTX_init(&dctx->ctx); + if (!HMAC_CTX_copy_ex(&dctx->ctx, &sctx->ctx)) { + return 0; + } + if (sctx->ktmp.data) { + if (!ASN1_OCTET_STRING_set(&dctx->ktmp, sctx->ktmp.data, + sctx->ktmp.length)) { + return 0; + } + } + return 1; +} + +static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx) { + HMAC_PKEY_CTX *hctx = ctx->data; + + if (hctx == NULL) { + return; + } + + HMAC_CTX_cleanup(&hctx->ctx); + if (hctx->ktmp.data) { + if (hctx->ktmp.length) { + OPENSSL_cleanse(hctx->ktmp.data, hctx->ktmp.length); + } + OPENSSL_free(hctx->ktmp.data); + hctx->ktmp.data = NULL; + } + OPENSSL_free(hctx); +} + +static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { + ASN1_OCTET_STRING *hkey = NULL; + HMAC_PKEY_CTX *hctx = ctx->data; + + if (!hctx->ktmp.data) { + return 0; + } + hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp); + if (!hkey) { + return 0; + } + EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey); + + return 1; +} + +static void int_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + HMAC_PKEY_CTX *hctx = ctx->pctx->data; + HMAC_Update(&hctx->ctx, data, count); +} + +static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) { + /* |mctx| gets repurposed as a hook to call |HMAC_Update|. Suppress the + * automatic setting of |mctx->update| and the rest of its initialization. */ + EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); + mctx->update = int_update; + return 1; +} + +static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + EVP_MD_CTX *mctx) { + unsigned int hlen; + HMAC_PKEY_CTX *hctx = ctx->data; + size_t md_size = EVP_MD_CTX_size(mctx); + + if (!sig) { + *siglen = md_size; + return 1; + } else if (*siglen < md_size) { + OPENSSL_PUT_ERROR(EVP, hmac_signctx, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + if (!HMAC_Final(&hctx->ctx, sig, &hlen)) { + return 0; + } + *siglen = (size_t)hlen; + return 1; +} + +static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { + HMAC_PKEY_CTX *hctx = ctx->data; + ASN1_OCTET_STRING *key; + + switch (type) { + case EVP_PKEY_CTRL_SET_MAC_KEY: + if ((!p2 && p1 > 0) || (p1 < -1)) { + return 0; + } + if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1)) { + return 0; + } + break; + + case EVP_PKEY_CTRL_MD: + hctx->md = p2; + break; + + case EVP_PKEY_CTRL_DIGESTINIT: + key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr; + if (!HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md, + ctx->engine)) { + return 0; + } + break; + + default: + OPENSSL_PUT_ERROR(EVP, pkey_hmac_ctrl, EVP_R_COMMAND_NOT_SUPPORTED); + return 0; + } + return 1; +} + +const EVP_PKEY_METHOD hmac_pkey_meth = { + EVP_PKEY_HMAC, 0 /* flags */, pkey_hmac_init, + pkey_hmac_copy, pkey_hmac_cleanup, 0 /* paramgen_init */, + 0 /* paramgen */, 0 /* keygen_init */, pkey_hmac_keygen, + 0 /* sign_init */, 0 /* sign */, 0 /* verify_init */, + 0 /* verify */, hmac_signctx_init, hmac_signctx, + 0 /* verifyctx_init */, 0 /* verifyctx */, 0 /* encrypt_init */, + 0 /* encrypt */, 0 /* decrypt_init */, 0 /* decrypt */, + 0 /* derive_init */, 0 /* derive */, pkey_hmac_ctrl, + 0, +}; diff --git a/src/crypto/evp/p_hmac_asn1.c b/src/crypto/evp/p_hmac_asn1.c new file mode 100644 index 0000000..8aa6676 --- /dev/null +++ b/src/crypto/evp/p_hmac_asn1.c @@ -0,0 +1,89 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 2007. + */ +/* ==================================================================== + * Copyright (c) 2007 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/digest.h> +#include <openssl/mem.h> +#include <openssl/obj.h> + +#include "internal.h" + + +static int hmac_size(const EVP_PKEY *pkey) { return EVP_MAX_MD_SIZE; } + +static void hmac_key_free(EVP_PKEY *pkey) { + ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr; + if (os) { + if (os->data) { + OPENSSL_cleanse(os->data, os->length); + } + ASN1_OCTET_STRING_free(os); + } +} + +const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = { + EVP_PKEY_HMAC, EVP_PKEY_HMAC, 0 /* flags */, + "HMAC", "OpenSSL HMAC method", 0 /* pub_decode */, + 0 /* pub_encode */, 0 /* pub_cmp */, 0 /* pub_print */, + 0 /*priv_decode */, 0 /* priv_encode */, 0 /* priv_print */, + 0 /* pkey_opaque */, 0 /* pkey_supports_digest */, + hmac_size, 0 /* pkey_bits */, 0 /* param_decode */, + 0 /* param_encode*/, 0 /* param_missing*/, 0 /* param_copy*/, + 0 /* param_cmp*/, 0 /* param_print*/, 0 /* sig_print*/, + hmac_key_free, 0 /* old_priv_decode */, + 0 /* old_priv_encode */ +}; diff --git a/src/crypto/evp/p_rsa.c b/src/crypto/evp/p_rsa.c index cfecbfd..5abc075 100644 --- a/src/crypto/evp/p_rsa.c +++ b/src/crypto/evp/p_rsa.c @@ -174,7 +174,7 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, } if (*siglen < key_len) { - OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + OPENSSL_PUT_ERROR(EVP, pkey_rsa_sign, EVP_R_BUFFER_TOO_SMALL); return 0; } @@ -182,12 +182,12 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, unsigned int out_len; if (tbslen != EVP_MD_size(rctx->md)) { - OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_DIGEST_LENGTH); + OPENSSL_PUT_ERROR(EVP, pkey_rsa_sign, EVP_R_INVALID_DIGEST_LENGTH); return 0; } if (EVP_MD_type(rctx->md) == NID_mdc2) { - OPENSSL_PUT_ERROR(EVP, EVP_R_NO_MDC2_SUPPORT); + OPENSSL_PUT_ERROR(EVP, pkey_rsa_sign, EVP_R_NO_MDC2_SUPPORT); return 0; } @@ -268,7 +268,7 @@ static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, } if (*outlen < key_len) { - OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + OPENSSL_PUT_ERROR(EVP, pkey_rsa_encrypt, EVP_R_BUFFER_TOO_SMALL); return 0; } @@ -300,7 +300,7 @@ static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, } if (*outlen < key_len) { - OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + OPENSSL_PUT_ERROR(EVP, pkey_rsa_decrypt, EVP_R_BUFFER_TOO_SMALL); return 0; } @@ -333,7 +333,7 @@ static int check_padding_md(const EVP_MD *md, int padding) { } if (padding == RSA_NO_PADDING) { - OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE); + OPENSSL_PUT_ERROR(EVP, check_padding_md, EVP_R_INVALID_PADDING_MODE); return 0; } @@ -361,7 +361,8 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { 0 == (ctx->operation & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) || (p1 == RSA_PKCS1_OAEP_PADDING && 0 == (ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))) { - OPENSSL_PUT_ERROR(EVP, EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); + OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, + EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); return 0; } if ((p1 == RSA_PKCS1_PSS_PADDING || p1 == RSA_PKCS1_OAEP_PADDING) && @@ -378,7 +379,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN: if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { - OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PSS_SALTLEN); + OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PSS_SALTLEN); return 0; } if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) { @@ -393,7 +394,7 @@ 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, EVP_R_INVALID_KEYBITS); + OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_KEYBITS); return 0; } rctx->nbits = p1; @@ -410,7 +411,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { case EVP_PKEY_CTRL_RSA_OAEP_MD: case EVP_PKEY_CTRL_GET_RSA_OAEP_MD: if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { - OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE); + OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE); return 0; } if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD) { @@ -435,7 +436,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING && rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { - OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_MGF1_MD); + OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_MGF1_MD); return 0; } if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) { @@ -451,7 +452,7 @@ 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, EVP_R_INVALID_PADDING_MODE); + OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE); return 0; } OPENSSL_free(rctx->oaep_label); @@ -468,14 +469,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, EVP_R_INVALID_PADDING_MODE); + OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE); return 0; } CBS_init((CBS *)p2, rctx->oaep_label, rctx->oaep_labellen); return 1; + case EVP_PKEY_CTRL_DIGESTINIT: + return 1; + default: - OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); + OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_COMMAND_NOT_SUPPORTED); return 0; } } @@ -505,13 +509,14 @@ static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { } const EVP_PKEY_METHOD rsa_pkey_meth = { - EVP_PKEY_RSA, 0 /* flags */, pkey_rsa_init, - pkey_rsa_copy, pkey_rsa_cleanup, 0 /* paramgen_init */, - 0 /* paramgen */, 0 /* keygen_init */, pkey_rsa_keygen, - 0 /* sign_init */, pkey_rsa_sign, 0 /* verify_init */, - pkey_rsa_verify, 0 /* encrypt_init */, pkey_rsa_encrypt, - 0 /* decrypt_init */, pkey_rsa_decrypt, 0 /* derive_init */, - 0 /* derive */, pkey_rsa_ctrl, + EVP_PKEY_RSA, 0 /* flags */, pkey_rsa_init, + pkey_rsa_copy, pkey_rsa_cleanup, 0 /* paramgen_init */, + 0 /* paramgen */, 0 /* keygen_init */, pkey_rsa_keygen, + 0 /* sign_init */, pkey_rsa_sign, 0 /* verify_init */, + pkey_rsa_verify, 0 /* signctx_init */, 0 /* signctx */, + 0 /* verifyctx_init */, 0 /* verifyctx */, 0 /* encrypt_init */, + pkey_rsa_encrypt, 0 /* decrypt_init */, pkey_rsa_decrypt, + 0 /* derive_init */, 0 /* derive */, pkey_rsa_ctrl, }; int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding) { @@ -588,7 +593,7 @@ int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, return -1; } if (CBS_len(&label) > INT_MAX) { - OPENSSL_PUT_ERROR(EVP, ERR_R_OVERFLOW); + OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_get0_rsa_oaep_label, ERR_R_OVERFLOW); return -1; } *out_label = CBS_data(&label); diff --git a/src/crypto/evp/p_rsa_asn1.c b/src/crypto/evp/p_rsa_asn1.c index f60625b..1e2d3f6 100644 --- a/src/crypto/evp/p_rsa_asn1.c +++ b/src/crypto/evp/p_rsa_asn1.c @@ -57,7 +57,6 @@ #include <openssl/asn1.h> #include <openssl/asn1t.h> -#include <openssl/bytestring.h> #include <openssl/digest.h> #include <openssl/err.h> #include <openssl/mem.h> @@ -70,14 +69,16 @@ static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { - uint8_t *encoded; - size_t encoded_len; - if (!RSA_public_key_to_bytes(&encoded, &encoded_len, pkey->pkey.rsa)) { + uint8_t *encoded = NULL; + int len; + len = i2d_RSAPublicKey(pkey->pkey.rsa, &encoded); + + if (len <= 0) { return 0; } if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA), V_ASN1_NULL, NULL, - encoded, encoded_len)) { + encoded, len)) { OPENSSL_free(encoded); return 0; } @@ -88,25 +89,16 @@ static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { const uint8_t *p; int pklen; + RSA *rsa; + if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey)) { return 0; } - - /* Estonian IDs issued between September 2014 to September 2015 are - * broken. See https://crbug.com/532048 and https://crbug.com/534766. - * - * TODO(davidben): Switch this to the strict version in March 2016 or when - * Chromium can force client certificates down a different codepath, whichever - * comes first. */ - CBS cbs; - CBS_init(&cbs, p, pklen); - RSA *rsa = RSA_parse_public_key_buggy(&cbs); - if (rsa == NULL || CBS_len(&cbs) != 0) { - OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - RSA_free(rsa); + rsa = d2i_RSAPublicKey(NULL, &p, pklen); + if (rsa == NULL) { + OPENSSL_PUT_ERROR(EVP, rsa_pub_decode, ERR_R_RSA_LIB); return 0; } - EVP_PKEY_assign_RSA(pkey, rsa); return 1; } @@ -117,17 +109,20 @@ static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { } static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { - uint8_t *encoded; - size_t encoded_len; - if (!RSA_private_key_to_bytes(&encoded, &encoded_len, pkey->pkey.rsa)) { + uint8_t *rk = NULL; + int rklen; + + rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk); + + if (rklen <= 0) { + OPENSSL_PUT_ERROR(EVP, rsa_priv_encode, ERR_R_MALLOC_FAILURE); return 0; } /* TODO(fork): const correctness in next line. */ if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_rsaEncryption), 0, - V_ASN1_NULL, NULL, encoded, encoded_len)) { - OPENSSL_free(encoded); - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + V_ASN1_NULL, NULL, rk, rklen)) { + OPENSSL_PUT_ERROR(EVP, rsa_priv_encode, ERR_R_MALLOC_FAILURE); return 0; } @@ -137,14 +132,16 @@ static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { const uint8_t *p; int pklen; + RSA *rsa; + if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8)) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(EVP, rsa_priv_decode, ERR_R_MALLOC_FAILURE); return 0; } - RSA *rsa = RSA_private_key_from_bytes(p, pklen); + rsa = d2i_RSAPrivateKey(NULL, &p, pklen); if (rsa == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_RSA_LIB); + OPENSSL_PUT_ERROR(EVP, rsa_priv_decode, ERR_R_RSA_LIB); return 0; } @@ -201,24 +198,11 @@ static int do_rsa_print(BIO *out, const RSA *rsa, int off, update_buflen(rsa->dmp1, &buf_len); update_buflen(rsa->dmq1, &buf_len); update_buflen(rsa->iqmp, &buf_len); - - if (rsa->additional_primes != NULL) { - size_t i; - - for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes); - i++) { - const RSA_additional_prime *ap = - sk_RSA_additional_prime_value(rsa->additional_primes, i); - update_buflen(ap->prime, &buf_len); - update_buflen(ap->exp, &buf_len); - update_buflen(ap->coeff, &buf_len); - } - } } m = (uint8_t *)OPENSSL_malloc(buf_len + 10); if (m == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(EVP, do_rsa_print, ERR_R_MALLOC_FAILURE); goto err; } @@ -257,28 +241,6 @@ static int do_rsa_print(BIO *out, const RSA *rsa, int off, !ASN1_bn_print(out, "coefficient:", rsa->iqmp, m, off)) { goto err; } - - if (rsa->additional_primes != NULL && - sk_RSA_additional_prime_num(rsa->additional_primes) > 0) { - size_t i; - - if (BIO_printf(out, "otherPrimeInfos:\n") <= 0) { - goto err; - } - for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes); - i++) { - const RSA_additional_prime *ap = - sk_RSA_additional_prime_value(rsa->additional_primes, i); - - if (BIO_printf(out, "otherPrimeInfo (prime %u):\n", - (unsigned)(i + 3)) <= 0 || - !ASN1_bn_print(out, "prime:", ap->prime, m, off) || - !ASN1_bn_print(out, "exponent:", ap->exp, m, off) || - !ASN1_bn_print(out, "coeff:", ap->coeff, m, off)) { - goto err; - } - } - } } ret = 1; @@ -445,18 +407,18 @@ static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, return 1; } -static int old_rsa_priv_decode(EVP_PKEY *pkey, const uint8_t **pder, +static int old_rsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) { RSA *rsa = d2i_RSAPrivateKey(NULL, pder, derlen); if (rsa == NULL) { - OPENSSL_PUT_ERROR(EVP, ERR_R_RSA_LIB); + OPENSSL_PUT_ERROR(EVP, old_rsa_priv_decode, ERR_R_RSA_LIB); return 0; } EVP_PKEY_assign_RSA(pkey, rsa); return 1; } -static int old_rsa_priv_encode(const EVP_PKEY *pkey, uint8_t **pder) { +static int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) { return i2d_RSAPrivateKey(pkey->pkey.rsa, pder); } @@ -512,7 +474,7 @@ static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg) { } md = EVP_get_digestbyobj(alg->algorithm); if (md == NULL) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_DIGEST); + OPENSSL_PUT_ERROR(EVP, rsa_algor_to_md, EVP_R_UNKNOWN_DIGEST); } return md; } @@ -525,16 +487,16 @@ static const EVP_MD *rsa_mgf1_to_md(X509_ALGOR *alg, X509_ALGOR *maskHash) { } /* Check mask and lookup mask hash algorithm */ if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_MASK_ALGORITHM); + OPENSSL_PUT_ERROR(EVP, rsa_mgf1_to_md, EVP_R_UNSUPPORTED_MASK_ALGORITHM); return NULL; } if (!maskHash) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_MASK_PARAMETER); + OPENSSL_PUT_ERROR(EVP, rsa_mgf1_to_md, EVP_R_UNSUPPORTED_MASK_PARAMETER); return NULL; } md = EVP_get_digestbyobj(maskHash->algorithm); if (md == NULL) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_MASK_DIGEST); + OPENSSL_PUT_ERROR(EVP, rsa_mgf1_to_md, EVP_R_UNKNOWN_MASK_DIGEST); return NULL; } return md; @@ -614,13 +576,13 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) { /* Sanity check: make sure it is PSS */ if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_SIGNATURE_TYPE); + OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_UNSUPPORTED_SIGNATURE_TYPE); return 0; } /* Decode PSS parameters */ pss = rsa_pss_decode(sigalg, &maskHash); if (pss == NULL) { - OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PSS_PARAMETERS); + OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_PSS_PARAMETERS); goto err; } @@ -640,7 +602,7 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) { /* Could perform more salt length sanity checks but the main * RSA routines will trap other invalid values anyway. */ if (saltlen < 0) { - OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_SALT_LENGTH); + OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_SALT_LENGTH); goto err; } } @@ -648,7 +610,7 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) { /* low-level routines support only trailer field 0xbc (value 1) * and PKCS#1 says we should reject any other value anyway. */ if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) { - OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_TRAILER); + OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_TRAILER); goto err; } @@ -676,7 +638,8 @@ static int rsa_digest_verify_init_from_algorithm(EVP_MD_CTX *ctx, EVP_PKEY *pkey) { /* Sanity check: make sure it is PSS */ if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_SIGNATURE_TYPE); + OPENSSL_PUT_ERROR(EVP, rsa_digest_verify_init_from_algorithm, + EVP_R_UNSUPPORTED_SIGNATURE_TYPE); return 0; } return rsa_pss_to_ctx(ctx, sigalg, pkey); @@ -708,6 +671,7 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = { ASN1_PKEY_SIGPARAM_NULL, "RSA", + "OpenSSL RSA method", rsa_pub_decode, rsa_pub_encode, |