From 8dbef010e7e6ecc07a9c8142cf26c8768fd55dc2 Mon Sep 17 00:00:00 2001 From: Shane Lontis Date: Tue, 22 Sep 2020 15:51:49 +1000 Subject: [PATCH] Fix ecx so that is uses a settable propertyquery Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/12944) --- crypto/ec/curve25519.c | 4 +- crypto/ec/curve448/curve448_local.h | 4 +- crypto/ec/curve448/ed448.h | 18 +++-- crypto/ec/curve448/eddsa.c | 63 +++++++++-------- crypto/ec/ecx_backend.c | 6 +- crypto/ec/ecx_key.c | 19 ++++-- crypto/ec/ecx_meth.c | 45 ++++++------- include/crypto/ecx.h | 12 ++-- providers/implementations/keymgmt/ecx_kmgmt.c | 67 +++++++++++++++---- providers/implementations/signature/eddsa.c | 6 +- test/curve448_internal_test.c | 22 +++--- 11 files changed, 165 insertions(+), 101 deletions(-) diff --git a/crypto/ec/curve25519.c b/crypto/ec/curve25519.c index 19fdb8d74f..b945c35f29 100644 --- a/crypto/ec/curve25519.c +++ b/crypto/ec/curve25519.c @@ -5578,14 +5578,14 @@ err: } int ED25519_public_from_private(OPENSSL_CTX *ctx, uint8_t out_public_key[32], - const uint8_t private_key[32]) + const uint8_t private_key[32], const char *propq) { uint8_t az[SHA512_DIGEST_LENGTH]; ge_p3 A; int r; EVP_MD *sha512 = NULL; - sha512 = EVP_MD_fetch(ctx, SN_sha512, NULL); + sha512 = EVP_MD_fetch(ctx, SN_sha512, propq); if (sha512 == NULL) return 0; r = EVP_Digest(private_key, 32, az, NULL, sha512, NULL); diff --git a/crypto/ec/curve448/curve448_local.h b/crypto/ec/curve448/curve448_local.h index 84dd157d94..62a61fd979 100644 --- a/crypto/ec/curve448/curve448_local.h +++ b/crypto/ec/curve448/curve448_local.h @@ -12,10 +12,10 @@ int ED448ph_sign(OPENSSL_CTX *ctx, uint8_t *out_sig, const uint8_t hash[64], const uint8_t public_key[57], const uint8_t private_key[57], - const uint8_t *context, size_t context_len); + const uint8_t *context, size_t context_len, const char *propq); int ED448ph_verify(OPENSSL_CTX *ctx, const uint8_t hash[64], const uint8_t signature[114], const uint8_t public_key[57], - const uint8_t *context, size_t context_len); + const uint8_t *context, size_t context_len, const char *propq); #endif /* OSSL_CRYPTO_EC_CURVE448_LOCAL_H */ diff --git a/crypto/ec/curve448/ed448.h b/crypto/ec/curve448/ed448.h index 4f99fe6901..16248b28cc 100644 --- a/crypto/ec/curve448/ed448.h +++ b/crypto/ec/curve448/ed448.h @@ -40,7 +40,8 @@ c448_error_t c448_ed448_derive_public_key( OPENSSL_CTX *ctx, uint8_t pubkey [EDDSA_448_PUBLIC_BYTES], - const uint8_t privkey [EDDSA_448_PRIVATE_BYTES]); + const uint8_t privkey [EDDSA_448_PRIVATE_BYTES], + const char *propq); /* * EdDSA signing. @@ -66,7 +67,8 @@ c448_error_t c448_ed448_sign( const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t *message, size_t message_len, uint8_t prehashed, const uint8_t *context, - size_t context_len); + size_t context_len, + const char *propq); /* * EdDSA signing with prehash. @@ -91,7 +93,8 @@ c448_error_t c448_ed448_sign_prehash( const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t hash[64], const uint8_t *context, - size_t context_len); + size_t context_len, + const char *propq); /* * EdDSA signature verification. @@ -118,7 +121,8 @@ c448_error_t c448_ed448_verify(OPENSSL_CTX *ctx, pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t *message, size_t message_len, uint8_t prehashed, const uint8_t *context, - uint8_t context_len); + uint8_t context_len, + const char *propq); /* * EdDSA signature verification. @@ -143,7 +147,8 @@ c448_error_t c448_ed448_verify_prehash( const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t hash[64], const uint8_t *context, - uint8_t context_len); + uint8_t context_len, + const char *propq); /* * EdDSA point encoding. Used internally, exposed externally. @@ -196,6 +201,7 @@ c448_error_t curve448_point_decode_like_eddsa_and_mul_by_ratio( c448_error_t c448_ed448_convert_private_key_to_x448( OPENSSL_CTX *ctx, uint8_t x[X448_PRIVATE_BYTES], - const uint8_t ed[EDDSA_448_PRIVATE_BYTES]); + const uint8_t ed[EDDSA_448_PRIVATE_BYTES], + const char *propq); #endif /* OSSL_CRYPTO_EC_CURVE448_ED448_H */ diff --git a/crypto/ec/curve448/eddsa.c b/crypto/ec/curve448/eddsa.c index f4fbaf7539..51a14642dc 100644 --- a/crypto/ec/curve448/eddsa.c +++ b/crypto/ec/curve448/eddsa.c @@ -21,7 +21,8 @@ #define COFACTOR 4 static c448_error_t oneshot_hash(OPENSSL_CTX *ctx, uint8_t *out, size_t outlen, - const uint8_t *in, size_t inlen) + const uint8_t *in, size_t inlen, + const char *propq) { EVP_MD_CTX *hashctx = EVP_MD_CTX_new(); EVP_MD *shake256 = NULL; @@ -30,7 +31,7 @@ static c448_error_t oneshot_hash(OPENSSL_CTX *ctx, uint8_t *out, size_t outlen, if (hashctx == NULL) return C448_FAILURE; - shake256 = EVP_MD_fetch(ctx, "SHAKE256", NULL); + shake256 = EVP_MD_fetch(ctx, "SHAKE256", propq); if (shake256 == NULL) goto err; @@ -57,7 +58,8 @@ static c448_error_t hash_init_with_dom(OPENSSL_CTX *ctx, EVP_MD_CTX *hashctx, uint8_t prehashed, uint8_t for_prehash, const uint8_t *context, - size_t context_len) + size_t context_len, + const char *propq) { #ifdef CHARSET_EBCDIC const char dom_s[] = {0x53, 0x69, 0x67, 0x45, @@ -75,7 +77,7 @@ static c448_error_t hash_init_with_dom(OPENSSL_CTX *ctx, EVP_MD_CTX *hashctx, - (for_prehash == 0 ? 1 : 0)); dom[1] = (uint8_t)context_len; - shake256 = EVP_MD_fetch(ctx, "SHAKE256", NULL); + shake256 = EVP_MD_fetch(ctx, "SHAKE256", propq); if (shake256 == NULL) return C448_FAILURE; @@ -95,18 +97,20 @@ static c448_error_t hash_init_with_dom(OPENSSL_CTX *ctx, EVP_MD_CTX *hashctx, c448_error_t c448_ed448_convert_private_key_to_x448( OPENSSL_CTX *ctx, uint8_t x[X448_PRIVATE_BYTES], - const uint8_t ed [EDDSA_448_PRIVATE_BYTES]) + const uint8_t ed [EDDSA_448_PRIVATE_BYTES], + const char *propq) { /* pass the private key through oneshot_hash function */ /* and keep the first X448_PRIVATE_BYTES bytes */ return oneshot_hash(ctx, x, X448_PRIVATE_BYTES, ed, - EDDSA_448_PRIVATE_BYTES); + EDDSA_448_PRIVATE_BYTES, propq); } c448_error_t c448_ed448_derive_public_key( OPENSSL_CTX *ctx, uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], - const uint8_t privkey[EDDSA_448_PRIVATE_BYTES]) + const uint8_t privkey[EDDSA_448_PRIVATE_BYTES], + const char *propq) { /* only this much used for keygen */ uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES]; @@ -116,7 +120,8 @@ c448_error_t c448_ed448_derive_public_key( if (!oneshot_hash(ctx, secret_scalar_ser, sizeof(secret_scalar_ser), privkey, - EDDSA_448_PRIVATE_BYTES)) + EDDSA_448_PRIVATE_BYTES, + propq)) return C448_FAILURE; clamp(secret_scalar_ser); @@ -154,7 +159,7 @@ c448_error_t c448_ed448_sign( const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t *message, size_t message_len, uint8_t prehashed, const uint8_t *context, - size_t context_len) + size_t context_len, const char *propq) { curve448_scalar_t secret_scalar; EVP_MD_CTX *hashctx = EVP_MD_CTX_new(); @@ -175,7 +180,7 @@ c448_error_t c448_ed448_sign( uint8_t expanded[EDDSA_448_PRIVATE_BYTES * 2]; if (!oneshot_hash(ctx, expanded, sizeof(expanded), privkey, - EDDSA_448_PRIVATE_BYTES)) + EDDSA_448_PRIVATE_BYTES, propq)) goto err; clamp(expanded); curve448_scalar_decode_long(secret_scalar, expanded, @@ -183,7 +188,7 @@ c448_error_t c448_ed448_sign( /* Hash to create the nonce */ if (!hash_init_with_dom(ctx, hashctx, prehashed, 0, context, - context_len) + context_len, propq) || !EVP_DigestUpdate(hashctx, expanded + EDDSA_448_PRIVATE_BYTES, EDDSA_448_PRIVATE_BYTES) @@ -224,7 +229,8 @@ c448_error_t c448_ed448_sign( uint8_t challenge[2 * EDDSA_448_PRIVATE_BYTES]; /* Compute the challenge */ - if (!hash_init_with_dom(ctx, hashctx, prehashed, 0, context, context_len) + if (!hash_init_with_dom(ctx, hashctx, prehashed, 0, context, context_len, + propq) || !EVP_DigestUpdate(hashctx, nonce_point, sizeof(nonce_point)) || !EVP_DigestUpdate(hashctx, pubkey, EDDSA_448_PUBLIC_BYTES) || !EVP_DigestUpdate(hashctx, message, message_len) @@ -260,10 +266,10 @@ c448_error_t c448_ed448_sign_prehash( const uint8_t privkey[EDDSA_448_PRIVATE_BYTES], const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t hash[64], const uint8_t *context, - size_t context_len) + size_t context_len, const char *propq) { return c448_ed448_sign(ctx, signature, privkey, pubkey, hash, 64, 1, - context, context_len); + context, context_len, propq); } c448_error_t c448_ed448_verify( @@ -272,7 +278,7 @@ c448_error_t c448_ed448_verify( const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t *message, size_t message_len, uint8_t prehashed, const uint8_t *context, - uint8_t context_len) + uint8_t context_len, const char *propq) { curve448_point_t pk_point, r_point; c448_error_t error; @@ -321,7 +327,7 @@ c448_error_t c448_ed448_verify( if (hashctx == NULL || !hash_init_with_dom(ctx, hashctx, prehashed, 0, context, - context_len) + context_len, propq) || !EVP_DigestUpdate(hashctx, signature, EDDSA_448_PUBLIC_BYTES) || !EVP_DigestUpdate(hashctx, pubkey, EDDSA_448_PUBLIC_BYTES) || !EVP_DigestUpdate(hashctx, message, message_len) @@ -354,50 +360,51 @@ c448_error_t c448_ed448_verify_prehash( const uint8_t signature[EDDSA_448_SIGNATURE_BYTES], const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t hash[64], const uint8_t *context, - uint8_t context_len) + uint8_t context_len, const char *propq) { return c448_ed448_verify(ctx, signature, pubkey, hash, 64, 1, context, - context_len); + context_len, propq); } int ED448_sign(OPENSSL_CTX *ctx, uint8_t *out_sig, const uint8_t *message, size_t message_len, const uint8_t public_key[57], const uint8_t private_key[57], const uint8_t *context, - size_t context_len) + size_t context_len, const char *propq) { return c448_ed448_sign(ctx, out_sig, private_key, public_key, message, - message_len, 0, context, context_len) + message_len, 0, context, context_len,propq) == C448_SUCCESS; } int ED448_verify(OPENSSL_CTX *ctx, const uint8_t *message, size_t message_len, const uint8_t signature[114], const uint8_t public_key[57], - const uint8_t *context, size_t context_len) + const uint8_t *context, size_t context_len, const char *propq) { return c448_ed448_verify(ctx, signature, public_key, message, message_len, - 0, context, (uint8_t)context_len) == C448_SUCCESS; + 0, context, (uint8_t)context_len, + propq) == C448_SUCCESS; } int ED448ph_sign(OPENSSL_CTX *ctx, uint8_t *out_sig, const uint8_t hash[64], const uint8_t public_key[57], const uint8_t private_key[57], - const uint8_t *context, size_t context_len) + const uint8_t *context, size_t context_len, const char *propq) { return c448_ed448_sign_prehash(ctx, out_sig, private_key, public_key, hash, - context, context_len) == C448_SUCCESS; + context, context_len, propq) == C448_SUCCESS; } int ED448ph_verify(OPENSSL_CTX *ctx, const uint8_t hash[64], const uint8_t signature[114], const uint8_t public_key[57], - const uint8_t *context, size_t context_len) + const uint8_t *context, size_t context_len, const char *propq) { return c448_ed448_verify_prehash(ctx, signature, public_key, hash, context, - (uint8_t)context_len) == C448_SUCCESS; + (uint8_t)context_len, propq) == C448_SUCCESS; } int ED448_public_from_private(OPENSSL_CTX *ctx, uint8_t out_public_key[57], - const uint8_t private_key[57]) + const uint8_t private_key[57], const char *propq) { - return c448_ed448_derive_public_key(ctx, out_public_key, private_key) + return c448_ed448_derive_public_key(ctx, out_public_key, private_key, propq) == C448_SUCCESS; } diff --git a/crypto/ec/ecx_backend.c b/crypto/ec/ecx_backend.c index 042f9ca8da..d1e652ae4f 100644 --- a/crypto/ec/ecx_backend.c +++ b/crypto/ec/ecx_backend.c @@ -27,7 +27,8 @@ int ecx_public_from_private(ECX_KEY *key) X25519_public_from_private(key->pubkey, key->privkey); break; case ECX_KEY_TYPE_ED25519: - if (!ED25519_public_from_private(key->libctx, key->pubkey, key->privkey)) { + if (!ED25519_public_from_private(key->libctx, key->pubkey, key->privkey, + key->propq)) { ECerr(0, EC_R_FAILED_MAKING_PUBLIC_KEY); return 0; } @@ -36,7 +37,8 @@ int ecx_public_from_private(ECX_KEY *key) X448_public_from_private(key->pubkey, key->privkey); break; case ECX_KEY_TYPE_ED448: - if (!ED448_public_from_private(key->libctx, key->pubkey, key->privkey)) { + if (!ED448_public_from_private(key->libctx, key->pubkey, key->privkey, + key->propq)) { ECerr(0, EC_R_FAILED_MAKING_PUBLIC_KEY); return 0; } diff --git a/crypto/ec/ecx_key.c b/crypto/ec/ecx_key.c index 46abd57a74..dd4b872ab0 100644 --- a/crypto/ec/ecx_key.c +++ b/crypto/ec/ecx_key.c @@ -10,7 +10,8 @@ #include #include "crypto/ecx.h" -ECX_KEY *ecx_key_new(OPENSSL_CTX *libctx, ECX_KEY_TYPE type, int haspubkey) +ECX_KEY *ecx_key_new(OPENSSL_CTX *libctx, ECX_KEY_TYPE type, int haspubkey, + const char *propq) { ECX_KEY *ret = OPENSSL_zalloc(sizeof(*ret)); @@ -36,14 +37,21 @@ ECX_KEY *ecx_key_new(OPENSSL_CTX *libctx, ECX_KEY_TYPE type, int haspubkey) ret->type = type; ret->references = 1; - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { + if (propq != NULL) { + ret->propq = OPENSSL_strdup(propq); ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); - OPENSSL_free(ret); - return NULL; + if (ret->propq == NULL) + goto err; } + ret->lock = CRYPTO_THREAD_lock_new(); + if (ret->lock == NULL) + goto err; return ret; +err: + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + OPENSSL_free(ret); + return NULL; } void ecx_key_free(ECX_KEY *key) @@ -59,6 +67,7 @@ void ecx_key_free(ECX_KEY *key) return; REF_ASSERT_ISNT(i < 0); + OPENSSL_free(key->propq); OPENSSL_secure_clear_free(key->privkey, key->keylen); CRYPTO_THREAD_lock_free(key->lock); OPENSSL_free(key); diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c index 75693e35f7..99f1e480c1 100644 --- a/crypto/ec/ecx_meth.c +++ b/crypto/ec/ecx_meth.c @@ -59,7 +59,7 @@ static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg, } } - key = ecx_key_new(libctx, KEYNID2TYPE(id), 1); + key = ecx_key_new(libctx, KEYNID2TYPE(id), 1, propq); if (key == NULL) { ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE); return 0; @@ -75,7 +75,7 @@ static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg, goto err; } if (op == KEY_OP_KEYGEN) { - if (RAND_priv_bytes(privkey, KEYLENID(id)) <= 0) + if (RAND_priv_bytes_ex(libctx, privkey, KEYLENID(id)) <= 0) goto err; if (id == EVP_PKEY_X25519) { privkey[0] &= 248; @@ -439,7 +439,8 @@ static int ecx_generic_import_from(const OSSL_PARAM params[], void *vpctx, { EVP_PKEY_CTX *pctx = vpctx; EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); - ECX_KEY *ecx = ecx_key_new(pctx->libctx, KEYNID2TYPE(keytype), 0); + ECX_KEY *ecx = ecx_key_new(pctx->libctx, KEYNID2TYPE(keytype), 0, + pctx->propquery); if (ecx == NULL) { ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); @@ -862,12 +863,8 @@ static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig, return 0; } - /* - * TODO(3.0): We use NULL for the library context for now. Will need to - * change later. - */ - if (ED448_sign(NULL, sig, tbs, tbslen, edkey->pubkey, edkey->privkey, - NULL, 0) == 0) + if (ED448_sign(edkey->libctx, sig, tbs, tbslen, edkey->pubkey, edkey->privkey, + NULL, 0, edkey->propq) == 0) return 0; *siglen = ED448_SIGSIZE; return 1; @@ -882,7 +879,8 @@ static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig, if (siglen != ED25519_SIGSIZE) return 0; - return ED25519_verify(tbs, tbslen, sig, edkey->pubkey, NULL, NULL); + return ED25519_verify(tbs, tbslen, sig, edkey->pubkey, + edkey->libctx, edkey->propq); } static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig, @@ -894,11 +892,8 @@ static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig, if (siglen != ED448_SIGSIZE) return 0; - /* - * TODO(3.0): We send NULL for the OPENSSL_CTX for now. This will need to - * change. - */ - return ED448_verify(NULL, tbs, tbslen, sig, edkey->pubkey, NULL, 0); + return ED448_verify(edkey->libctx, tbs, tbslen, sig, edkey->pubkey, NULL, 0, + edkey->propq); } static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) @@ -949,7 +944,8 @@ static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X25519, 1); + ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X25519, 1, + ctx->propquery); unsigned char *privkey = NULL, *pubkey; if (key == NULL) { @@ -965,7 +961,7 @@ static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) goto err; } - if (RAND_priv_bytes(privkey, X25519_KEYLEN) <= 0) + if (RAND_priv_bytes_ex(ctx->libctx, privkey, X25519_KEYLEN) <= 0) goto err; privkey[0] &= 248; @@ -991,7 +987,8 @@ static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X448, 1); + ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X448, 1, + ctx->propquery); unsigned char *privkey = NULL, *pubkey; if (key == NULL) { @@ -1007,7 +1004,7 @@ static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) goto err; } - if (RAND_priv_bytes(privkey, X448_KEYLEN) <= 0) + if (RAND_priv_bytes_ex(ctx->libctx, privkey, X448_KEYLEN) <= 0) goto err; privkey[0] &= 252; @@ -1036,7 +1033,8 @@ static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, }; unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH]; - ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED25519, 1); + ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED25519, 1, + ctx->propquery); unsigned char *privkey = NULL, *pubkey; unsigned int sz; @@ -1053,7 +1051,7 @@ static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) goto err; } - if (RAND_priv_bytes(privkey, ED25519_KEYLEN) <= 0) + if (RAND_priv_bytes_ex(ctx->libctx, privkey, ED25519_KEYLEN) <= 0) goto err; if (!EVP_Digest(privkey, 32, buff, &sz, EVP_sha512(), NULL)) @@ -1093,7 +1091,8 @@ static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00 }; unsigned char x_dst[57], buff[114]; - ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED448, 1); + ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED448, 1, + ctx->propquery); unsigned char *privkey = NULL, *pubkey; EVP_MD_CTX *hashctx = NULL; @@ -1110,7 +1109,7 @@ static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) goto err; } - if (RAND_priv_bytes(privkey, ED448_KEYLEN) <= 0) + if (RAND_priv_bytes_ex(ctx->libctx, privkey, ED448_KEYLEN) <= 0) goto err; hashctx = EVP_MD_CTX_new(); diff --git a/include/crypto/ecx.h b/include/crypto/ecx.h index 54ce5f2b7c..72cf5dd843 100644 --- a/include/crypto/ecx.h +++ b/include/crypto/ecx.h @@ -62,6 +62,7 @@ typedef enum { struct ecx_key_st { OPENSSL_CTX *libctx; + char *propq; unsigned int haspubkey:1; unsigned char pubkey[MAX_KEYLEN]; unsigned char *privkey; @@ -74,7 +75,8 @@ struct ecx_key_st { typedef struct ecx_key_st ECX_KEY; size_t ecx_key_length(ECX_KEY_TYPE type); -ECX_KEY *ecx_key_new(OPENSSL_CTX *libctx, ECX_KEY_TYPE type, int haspubkey); +ECX_KEY *ecx_key_new(OPENSSL_CTX *libctx, ECX_KEY_TYPE type, int haspubkey, + const char *propq); unsigned char *ecx_key_allocate_privkey(ECX_KEY *key); void ecx_key_free(ECX_KEY *key); int ecx_key_up_ref(ECX_KEY *key); @@ -85,7 +87,7 @@ void X25519_public_from_private(uint8_t out_public_value[32], const uint8_t private_key[32]); int ED25519_public_from_private(OPENSSL_CTX *ctx, uint8_t out_public_key[32], - const uint8_t private_key[32]); + const uint8_t private_key[32], const char *propq); int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, const uint8_t public_key[32], const uint8_t private_key[32], OPENSSL_CTX *libctx, const char *propq); @@ -94,15 +96,15 @@ int ED25519_verify(const uint8_t *message, size_t message_len, OPENSSL_CTX *libctx, const char *propq); int ED448_public_from_private(OPENSSL_CTX *ctx, uint8_t out_public_key[57], - const uint8_t private_key[57]); + const uint8_t private_key[57], const char *propq); int ED448_sign(OPENSSL_CTX *ctx, uint8_t *out_sig, const uint8_t *message, size_t message_len, const uint8_t public_key[57], const uint8_t private_key[57], const uint8_t *context, - size_t context_len); + size_t context_len, const char *propq); int ED448_verify(OPENSSL_CTX *ctx, const uint8_t *message, size_t message_len, const uint8_t signature[114], const uint8_t public_key[57], - const uint8_t *context, size_t context_len); + const uint8_t *context, size_t context_len, const char *propq); int X448(uint8_t out_shared_key[56], const uint8_t private_key[56], const uint8_t peer_public_value[56]); diff --git a/providers/implementations/keymgmt/ecx_kmgmt.c b/providers/implementations/keymgmt/ecx_kmgmt.c index 6e1a2c91c8..b3d24e4c68 100644 --- a/providers/implementations/keymgmt/ecx_kmgmt.c +++ b/providers/implementations/keymgmt/ecx_kmgmt.c @@ -69,6 +69,7 @@ static OSSL_FUNC_keymgmt_export_types_fn ecx_imexport_types; struct ecx_gen_ctx { OPENSSL_CTX *libctx; + char *propq; ECX_KEY_TYPE type; int selection; }; @@ -84,28 +85,32 @@ static void *x25519_new_key(void *provctx) { if (!ossl_prov_is_running()) return 0; - return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_X25519, 0); + return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_X25519, 0, + NULL); } static void *x448_new_key(void *provctx) { if (!ossl_prov_is_running()) return 0; - return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_X448, 0); + return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_X448, 0, + NULL); } static void *ed25519_new_key(void *provctx) { if (!ossl_prov_is_running()) return 0; - return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_ED25519, 0); + return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_ED25519, 0, + NULL); } static void *ed448_new_key(void *provctx) { if (!ossl_prov_is_running()) return 0; - return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_ED448, 0); + return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_ED448, 0, + NULL); } static int ecx_has(void *keydata, int selection) @@ -345,6 +350,20 @@ static const OSSL_PARAM *ed448_gettable_params(void *provctx) return ed_gettable_params; } +static int set_property_query(ECX_KEY *ecxkey, const char *propq) +{ + OPENSSL_free(ecxkey->propq); + ecxkey->propq = NULL; + if (propq != NULL) { + ecxkey->propq = OPENSSL_strdup(propq); + if (ecxkey->propq == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return 0; + } + } + return 1; +} + static int ecx_set_params(void *key, const OSSL_PARAM params[]) { ECX_KEY *ecxkey = key; @@ -362,6 +381,12 @@ static int ecx_set_params(void *key, const OSSL_PARAM params[]) ecxkey->privkey = NULL; ecxkey->haspubkey = 1; } + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PROPERTIES); + if (p != NULL) { + if (p->data_type != OSSL_PARAM_UTF8_STRING + || !set_property_query(ecxkey, p->data)) + return 0; + } return 1; } @@ -388,6 +413,7 @@ static int ed448_set_params(void *key, const OSSL_PARAM params[]) static const OSSL_PARAM ecx_settable_params[] = { OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, NULL, 0), OSSL_PARAM_END }; @@ -423,7 +449,7 @@ static void *ecx_gen_init(void *provctx, int selection, ECX_KEY_TYPE type) if (!ossl_prov_is_running()) return NULL; - if ((gctx = OPENSSL_malloc(sizeof(*gctx))) != NULL) { + if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) { gctx->libctx = libctx; gctx->type = type; gctx->selection = selection; @@ -486,6 +512,15 @@ static int ecx_gen_set_params(void *genctx, const OSSL_PARAM params[]) return 0; } } + p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PROPERTIES); + if (p != NULL) { + if (p->data_type != OSSL_PARAM_UTF8_STRING) + return 0; + OPENSSL_free(gctx->propq); + gctx->propq = OPENSSL_strdup(p->data); + if (gctx->propq == NULL) + return 0; + } return 1; } @@ -494,6 +529,7 @@ static const OSSL_PARAM *ecx_gen_settable_params(void *provctx) { static OSSL_PARAM settable[] = { OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), OSSL_PARAM_END }; return settable; @@ -506,7 +542,7 @@ static void *ecx_gen(struct ecx_gen_ctx *gctx) if (gctx == NULL) return NULL; - if ((key = ecx_key_new(gctx->libctx, gctx->type, 0)) == NULL) { + if ((key = ecx_key_new(gctx->libctx, gctx->type, 0, gctx->propq)) == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; } @@ -534,11 +570,13 @@ static void *ecx_gen(struct ecx_gen_ctx *gctx) X448_public_from_private(key->pubkey, privkey); break; case ECX_KEY_TYPE_ED25519: - if (!ED25519_public_from_private(gctx->libctx, key->pubkey, privkey)) + if (!ED25519_public_from_private(gctx->libctx, key->pubkey, privkey, + gctx->propq)) goto err; break; case ECX_KEY_TYPE_ED448: - if (!ED448_public_from_private(gctx->libctx, key->pubkey, privkey)) + if (!ED448_public_from_private(gctx->libctx, key->pubkey, privkey, + gctx->propq)) goto err; break; } @@ -614,6 +652,7 @@ static void ecx_gen_cleanup(void *genctx) { struct ecx_gen_ctx *gctx = genctx; + OPENSSL_free(gctx->propq); OPENSSL_free(gctx); } @@ -670,7 +709,7 @@ static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X25519, 1); + ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X25519, 1, gctx->propq); unsigned char *privkey = NULL, *pubkey; if (key == NULL) { @@ -715,7 +754,7 @@ static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X448, 1); + ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X448, 1, gctx->propq); unsigned char *privkey = NULL, *pubkey; if (key == NULL) { @@ -763,7 +802,7 @@ static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx) 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, }; unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH]; - ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED25519, 1); + ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED25519, 1, gctx->propq); unsigned char *privkey = NULL, *pubkey; unsigned int sz; EVP_MD *sha = NULL; @@ -789,7 +828,7 @@ static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx) if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED25519_KEYLEN) <= 0) goto err; - sha = EVP_MD_fetch(gctx->libctx, "SHA512", NULL); + sha = EVP_MD_fetch(gctx->libctx, "SHA512", gctx->propq); if (sha == NULL) goto err; j = EVP_Digest(privkey, 32, buff, &sz, sha, NULL); @@ -830,7 +869,7 @@ static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx) 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00 }; unsigned char x_dst[57], buff[114]; - ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED448, 1); + ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED448, 1, gctx->propq); unsigned char *privkey = NULL, *pubkey; EVP_MD_CTX *hashctx = NULL; EVP_MD *shake = NULL; @@ -852,7 +891,7 @@ static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx) goto err; } - shake = EVP_MD_fetch(gctx->libctx, "SHAKE256", NULL); + shake = EVP_MD_fetch(gctx->libctx, "SHAKE256", gctx->propq); if (shake == NULL) goto err; if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED448_KEYLEN) <= 0) diff --git a/providers/implementations/signature/eddsa.c b/providers/implementations/signature/eddsa.c index 9d8ab0ad3e..19e9c62019 100644 --- a/providers/implementations/signature/eddsa.c +++ b/providers/implementations/signature/eddsa.c @@ -163,7 +163,7 @@ int ed448_digest_sign(void *vpeddsactx, unsigned char *sigret, } if (ED448_sign(peddsactx->libctx, sigret, tbs, tbslen, edkey->pubkey, - edkey->privkey, NULL, 0) == 0) { + edkey->privkey, NULL, 0, edkey->propq) == 0) { PROVerr(0, PROV_R_FAILED_TO_SIGN); return 0; } @@ -182,7 +182,7 @@ int ed25519_digest_verify(void *vpeddsactx, const unsigned char *sig, return 0; return ED25519_verify(tbs, tbslen, sig, edkey->pubkey, peddsactx->libctx, - NULL); + edkey->propq); } int ed448_digest_verify(void *vpeddsactx, const unsigned char *sig, @@ -196,7 +196,7 @@ int ed448_digest_verify(void *vpeddsactx, const unsigned char *sig, return 0; return ED448_verify(peddsactx->libctx, tbs, tbslen, sig, edkey->pubkey, - NULL, 0); + NULL, 0, edkey->propq); } static void eddsa_freectx(void *vpeddsactx) diff --git a/test/curve448_internal_test.c b/test/curve448_internal_test.c index 1c1510a361..b1df82e837 100644 --- a/test/curve448_internal_test.c +++ b/test/curve448_internal_test.c @@ -602,39 +602,39 @@ static int test_ed448(void) if (!TEST_ptr(hashctx) || !TEST_true(ED448_sign(NULL, outsig, NULL, 0, pubkey1, privkey1, - NULL, 0)) + NULL, 0, NULL)) || !TEST_int_eq(memcmp(sig1, outsig, sizeof(sig1)), 0) || !TEST_true(ED448_sign(NULL, outsig, msg2, sizeof(msg2), pubkey2, - privkey2, NULL, 0)) + privkey2, NULL, 0, NULL)) || !TEST_int_eq(memcmp(sig2, outsig, sizeof(sig2)), 0) || !TEST_true(ED448_sign(NULL, outsig, msg3, sizeof(msg3), pubkey3, - privkey3, context3, sizeof(context3))) + privkey3, context3, sizeof(context3), NULL)) || !TEST_int_eq(memcmp(sig3, outsig, sizeof(sig3)), 0) || !TEST_true(ED448_sign(NULL, outsig, msg4, sizeof(msg4), pubkey4, - privkey4, NULL, 0)) + privkey4, NULL, 0, NULL)) || !TEST_int_eq(memcmp(sig4, outsig, sizeof(sig4)), 0) || !TEST_true(ED448_sign(NULL, outsig, msg5, sizeof(msg5), pubkey5, - privkey5, NULL, 0)) + privkey5, NULL, 0, NULL)) || !TEST_int_eq(memcmp(sig5, outsig, sizeof(sig5)), 0) || !TEST_true(ED448_sign(NULL, outsig, msg6, sizeof(msg6), pubkey6, - privkey6, NULL, 0)) + privkey6, NULL, 0, NULL)) || !TEST_int_eq(memcmp(sig6, outsig, sizeof(sig6)), 0) || !TEST_true(ED448_sign(NULL, outsig, msg7, sizeof(msg7), pubkey7, - privkey7, NULL, 0)) + privkey7, NULL, 0, NULL)) || !TEST_int_eq(memcmp(sig7, outsig, sizeof(sig7)), 0) || !TEST_true(ED448_sign(NULL, outsig, msg8, sizeof(msg8), pubkey8, - privkey8, NULL, 0)) + privkey8, NULL, 0, NULL)) || !TEST_int_eq(memcmp(sig8, outsig, sizeof(sig8)), 0) || !TEST_true(ED448_sign(NULL, outsig, msg9, sizeof(msg9), pubkey9, - privkey9, NULL, 0)) + privkey9, NULL, 0, NULL)) || !TEST_int_eq(memcmp(sig9, outsig, sizeof(sig9)), 0) || !TEST_true(ED448ph_sign(NULL, outsig, dohash(hashctx, phmsg1, sizeof(phmsg1)), phpubkey1, phprivkey1, - NULL, 0)) + NULL, 0, NULL)) || !TEST_int_eq(memcmp(phsig1, outsig, sizeof(phsig1)), 0) || !TEST_true(ED448ph_sign(NULL, outsig, dohash(hashctx, phmsg2, sizeof(phmsg2)), phpubkey2, phprivkey2, - phcontext2, sizeof(phcontext2))) + phcontext2, sizeof(phcontext2), NULL)) || !TEST_int_eq(memcmp(phsig2, outsig, sizeof(phsig2)), 0)) { EVP_MD_CTX_free(hashctx); return 0; -- 2.34.1