summaryrefslogtreecommitdiffstats
path: root/src/crypto/evp
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/evp')
-rw-r--r--src/crypto/evp/CMakeLists.txt6
-rw-r--r--src/crypto/evp/algorithm.c18
-rw-r--r--src/crypto/evp/asn1.c (renamed from src/crypto/evp/evp_asn1.c)11
-rw-r--r--src/crypto/evp/digestsign.c72
-rw-r--r--src/crypto/evp/evp.c53
-rw-r--r--src/crypto/evp/evp_ctx.c77
-rw-r--r--src/crypto/evp/evp_extra_test.cc4
-rw-r--r--src/crypto/evp/evp_test.cc64
-rw-r--r--src/crypto/evp/evp_tests.txt5
-rw-r--r--src/crypto/evp/internal.h69
-rw-r--r--src/crypto/evp/p_dsa_asn1.c44
-rw-r--r--src/crypto/evp/p_ec.c52
-rw-r--r--src/crypto/evp/p_ec_asn1.c42
-rw-r--r--src/crypto/evp/p_hmac.c223
-rw-r--r--src/crypto/evp/p_hmac_asn1.c89
-rw-r--r--src/crypto/evp/p_rsa.c49
-rw-r--r--src/crypto/evp/p_rsa_asn1.c116
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, &params->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,