diff options
-rw-r--r-- | crypto/ec/ecx_meth.c | 49 | ||||
-rw-r--r-- | crypto/err/openssl.txt | 3 | ||||
-rw-r--r-- | crypto/evp/evp_err.c | 5 | ||||
-rw-r--r-- | crypto/evp/p_lib.c | 34 | ||||
-rw-r--r-- | crypto/hmac/hm_ameth.c | 21 | ||||
-rw-r--r-- | crypto/include/internal/asn1_int.h | 2 | ||||
-rw-r--r-- | crypto/poly1305/poly1305_ameth.c | 21 | ||||
-rw-r--r-- | crypto/siphash/siphash_ameth.c | 21 | ||||
-rw-r--r-- | include/openssl/evp.h | 5 | ||||
-rw-r--r-- | include/openssl/evperr.h | 3 | ||||
-rw-r--r-- | util/libcrypto.num | 2 |
11 files changed, 166 insertions, 0 deletions
diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c index d2aa6dd870..e75e07b052 100644 --- a/crypto/ec/ecx_meth.c +++ b/crypto/ec/ecx_meth.c @@ -354,6 +354,47 @@ static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len) KEY_OP_PUBLIC); } +static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv, + size_t *len) +{ + const ECX_KEY *key = pkey->pkey.ecx; + + if (priv == NULL) { + *len = KEYLENID(pkey->ameth->pkey_id); + return 1; + } + + if (key == NULL + || key->privkey == NULL + || *len < (size_t)KEYLENID(pkey->ameth->pkey_id)) + return 0; + + *len = KEYLENID(pkey->ameth->pkey_id); + memcpy(priv, key->privkey, *len); + + return 1; +} + +static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub, + size_t *len) +{ + const ECX_KEY *key = pkey->pkey.ecx; + + if (pub == NULL) { + *len = KEYLENID(pkey->ameth->pkey_id); + return 1; + } + + if (key == NULL + || *len < (size_t)KEYLENID(pkey->ameth->pkey_id)) + return 0; + + *len = KEYLENID(pkey->ameth->pkey_id); + memcpy(pub, key->pubkey, *len); + + return 1; +} + const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = { EVP_PKEY_X25519, EVP_PKEY_X25519, @@ -393,6 +434,8 @@ const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = { ecx_set_priv_key, ecx_set_pub_key, + ecx_get_priv_key, + ecx_get_pub_key, }; const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = { @@ -434,6 +477,8 @@ const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = { ecx_set_priv_key, ecx_set_pub_key, + ecx_get_priv_key, + ecx_get_pub_key, }; static int ecd_size25519(const EVP_PKEY *pkey) @@ -547,6 +592,8 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = { ecx_set_priv_key, ecx_set_pub_key, + ecx_get_priv_key, + ecx_get_pub_key, }; const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = { @@ -587,6 +634,8 @@ const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = { ecx_set_priv_key, ecx_set_pub_key, + ecx_get_priv_key, + ecx_get_pub_key, }; static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index afd7e38e3b..bd54c8bfc2 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -757,6 +757,8 @@ EVP_F_EVP_PKEY_GET0_HMAC:183:EVP_PKEY_get0_hmac EVP_F_EVP_PKEY_GET0_POLY1305:184:EVP_PKEY_get0_poly1305 EVP_F_EVP_PKEY_GET0_RSA:121:EVP_PKEY_get0_RSA EVP_F_EVP_PKEY_GET0_SIPHASH:172:EVP_PKEY_get0_siphash +EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY:202:EVP_PKEY_get_raw_private_key +EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY:203:EVP_PKEY_get_raw_public_key EVP_F_EVP_PKEY_KEYGEN:146:EVP_PKEY_keygen EVP_F_EVP_PKEY_KEYGEN_INIT:147:EVP_PKEY_keygen_init EVP_F_EVP_PKEY_METH_ADD0:194:EVP_PKEY_meth_add0 @@ -2199,6 +2201,7 @@ EVP_R_EXPECTING_A_EC_KEY:142:expecting a ec key EVP_R_EXPECTING_A_POLY1305_KEY:164:expecting a poly1305 key EVP_R_EXPECTING_A_SIPHASH_KEY:175:expecting a siphash key EVP_R_FIPS_MODE_NOT_SUPPORTED:167:fips mode not supported +EVP_R_GET_RAW_KEY_FAILED:182:get raw key failed EVP_R_ILLEGAL_SCRYPT_PARAMETERS:171:illegal scrypt parameters EVP_R_INITIALIZATION_ERROR:134:initialization error EVP_R_INPUT_NOT_INITIALIZED:111:input not initialized diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index 01ed97ed73..809adff288 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -93,6 +93,10 @@ static const ERR_STRING_DATA EVP_str_functs[] = { {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_RSA, 0), "EVP_PKEY_get0_RSA"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET0_SIPHASH, 0), "EVP_PKEY_get0_siphash"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY, 0), + "EVP_PKEY_get_raw_private_key"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY, 0), + "EVP_PKEY_get_raw_public_key"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_KEYGEN, 0), "EVP_PKEY_keygen"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_KEYGEN_INIT, 0), "EVP_PKEY_keygen_init"}, @@ -185,6 +189,7 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { "expecting a siphash key"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_GET_RAW_KEY_FAILED), "get raw key failed"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ILLEGAL_SCRYPT_PARAMETERS), "illegal scrypt parameters"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INITIALIZATION_ERROR), diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index e4d2bb1835..d78f1d2d84 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -280,6 +280,40 @@ EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e, return NULL; } +int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv, + size_t *len) +{ + if (pkey->ameth->get_priv_key == NULL) { + EVPerr(EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + if (!pkey->ameth->get_priv_key(pkey, priv, len)) { + EVPerr(EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY, EVP_R_GET_RAW_KEY_FAILED); + return 0; + } + + return 1; +} + +int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub, + size_t *len) +{ + if (pkey->ameth->get_pub_key == NULL) { + EVPerr(EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + if (!pkey->ameth->get_pub_key(pkey, pub, len)) { + EVPerr(EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY, EVP_R_GET_RAW_KEY_FAILED); + return 0; + } + + return 1; +} + EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, size_t len, const EVP_CIPHER *cipher) { diff --git a/crypto/hmac/hm_ameth.c b/crypto/hmac/hm_ameth.c index b786db07aa..fa204e9068 100644 --- a/crypto/hmac/hm_ameth.c +++ b/crypto/hmac/hm_ameth.c @@ -72,6 +72,25 @@ static int hmac_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv, return 1; } +static int hmac_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv, + size_t *len) +{ + ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr; + + if (priv == NULL) { + *len = ASN1_STRING_length(os); + return 1; + } + + if (os == NULL || *len < (size_t)ASN1_STRING_length(os)) + return 0; + + *len = ASN1_STRING_length(os); + memcpy(priv, ASN1_STRING_get0_data(os), *len); + + return 1; +} + const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = { EVP_PKEY_HMAC, EVP_PKEY_HMAC, @@ -103,4 +122,6 @@ const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = { hmac_set_priv_key, NULL, + hmac_get_priv_key, + NULL, }; diff --git a/crypto/include/internal/asn1_int.h b/crypto/include/internal/asn1_int.h index 962c3c6302..b8a6762aa1 100644 --- a/crypto/include/internal/asn1_int.h +++ b/crypto/include/internal/asn1_int.h @@ -61,6 +61,8 @@ struct evp_pkey_asn1_method_st { /* Get/set raw private/public key data */ int (*set_priv_key) (EVP_PKEY *pk, const unsigned char *priv, size_t len); int (*set_pub_key) (EVP_PKEY *pk, const unsigned char *pub, size_t len); + int (*get_priv_key) (const EVP_PKEY *pk, unsigned char *priv, size_t *len); + int (*get_pub_key) (const EVP_PKEY *pk, unsigned char *pub, size_t *len); } /* EVP_PKEY_ASN1_METHOD */ ; DEFINE_STACK_OF_CONST(EVP_PKEY_ASN1_METHOD) diff --git a/crypto/poly1305/poly1305_ameth.c b/crypto/poly1305/poly1305_ameth.c index ed4115b718..033ee8cd96 100644 --- a/crypto/poly1305/poly1305_ameth.c +++ b/crypto/poly1305/poly1305_ameth.c @@ -67,6 +67,25 @@ static int poly1305_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv, return 1; } +static int poly1305_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv, + size_t *len) +{ + ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr; + + if (priv == NULL) { + *len = POLY1305_KEY_SIZE; + return 1; + } + + if (os == NULL || *len < POLY1305_KEY_SIZE) + return 0; + + memcpy(priv, ASN1_STRING_get0_data(os), ASN1_STRING_length(os)); + *len = POLY1305_KEY_SIZE; + + return 1; +} + const EVP_PKEY_ASN1_METHOD poly1305_asn1_meth = { EVP_PKEY_POLY1305, EVP_PKEY_POLY1305, @@ -98,4 +117,6 @@ const EVP_PKEY_ASN1_METHOD poly1305_asn1_meth = { poly1305_set_priv_key, NULL, + poly1305_get_priv_key, + NULL, }; diff --git a/crypto/siphash/siphash_ameth.c b/crypto/siphash/siphash_ameth.c index 6411501bc0..c0ab7efae4 100644 --- a/crypto/siphash/siphash_ameth.c +++ b/crypto/siphash/siphash_ameth.c @@ -68,6 +68,25 @@ static int siphash_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv, return 1; } +static int siphash_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv, + size_t *len) +{ + ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr; + + if (priv == NULL) { + *len = SIPHASH_KEY_SIZE; + return 1; + } + + if (os == NULL || *len < SIPHASH_KEY_SIZE) + return 0; + + memcpy(priv, ASN1_STRING_get0_data(os), ASN1_STRING_length(os)); + *len = SIPHASH_KEY_SIZE; + + return 1; +} + const EVP_PKEY_ASN1_METHOD siphash_asn1_meth = { EVP_PKEY_SIPHASH, EVP_PKEY_SIPHASH, @@ -99,4 +118,6 @@ const EVP_PKEY_ASN1_METHOD siphash_asn1_meth = { siphash_set_priv_key, NULL, + siphash_get_priv_key, + NULL, }; diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 63cba15a6f..8e4e3fe227 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -1352,6 +1352,11 @@ EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e, EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e, const unsigned char *pub, size_t len); +int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv, + size_t *len); +int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub, + size_t *len); + EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, size_t len, const EVP_CIPHER *cipher); diff --git a/include/openssl/evperr.h b/include/openssl/evperr.h index 84f29518b0..a8f79c74a9 100644 --- a/include/openssl/evperr.h +++ b/include/openssl/evperr.h @@ -79,6 +79,8 @@ int ERR_load_EVP_strings(void); # define EVP_F_EVP_PKEY_GET0_POLY1305 184 # define EVP_F_EVP_PKEY_GET0_RSA 121 # define EVP_F_EVP_PKEY_GET0_SIPHASH 172 +# define EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY 202 +# define EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY 203 # define EVP_F_EVP_PKEY_KEYGEN 146 # define EVP_F_EVP_PKEY_KEYGEN_INIT 147 # define EVP_F_EVP_PKEY_METH_ADD0 194 @@ -139,6 +141,7 @@ int ERR_load_EVP_strings(void); # define EVP_R_EXPECTING_A_POLY1305_KEY 164 # define EVP_R_EXPECTING_A_SIPHASH_KEY 175 # define EVP_R_FIPS_MODE_NOT_SUPPORTED 167 +# define EVP_R_GET_RAW_KEY_FAILED 182 # define EVP_R_ILLEGAL_SCRYPT_PARAMETERS 171 # define EVP_R_INITIALIZATION_ERROR 134 # define EVP_R_INPUT_NOT_INITIALIZED 111 diff --git a/util/libcrypto.num b/util/libcrypto.num index a8107555a0..50dcd36a37 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -4563,3 +4563,5 @@ X509_OBJECT_set1_X509 4514 1_1_0i EXIST::FUNCTION: X509_LOOKUP_meth_get_get_by_issuer_serial 4515 1_1_0i EXIST::FUNCTION: X509_LOOKUP_meth_set_init 4516 1_1_0i EXIST::FUNCTION: X509_OBJECT_set1_X509_CRL 4517 1_1_0i EXIST::FUNCTION: +EVP_PKEY_get_raw_public_key 4518 1_1_1 EXIST::FUNCTION: +EVP_PKEY_get_raw_private_key 4519 1_1_1 EXIST::FUNCTION: |