From 0409767e69fc50a07221a06b59b4107997b2c0c4 Mon Sep 17 00:00:00 2001 From: jsing Date: Thu, 10 Nov 2022 14:46:44 +0000 Subject: [PATCH] Port EVP raw key API from OpenSSL. This will be needed to deal with Curve25519 based keys. ok beck@ tb@ --- lib/libcrypto/asn1/asn1_locl.h | 11 +++- lib/libcrypto/evp/evp.h | 14 ++++- lib/libcrypto/evp/evp_err.c | 3 +- lib/libcrypto/evp/p_lib.c | 93 +++++++++++++++++++++++++++++++++- 4 files changed, 116 insertions(+), 5 deletions(-) diff --git a/lib/libcrypto/asn1/asn1_locl.h b/lib/libcrypto/asn1/asn1_locl.h index e15b98b7c3d..8180e9b0fc2 100644 --- a/lib/libcrypto/asn1/asn1_locl.h +++ b/lib/libcrypto/asn1/asn1_locl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: asn1_locl.h,v 1.40 2022/11/08 12:56:00 beck Exp $ */ +/* $OpenBSD: asn1_locl.h,v 1.41 2022/11/10 14:46:44 jsing Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ @@ -142,6 +142,15 @@ struct evp_pkey_asn1_method_st { int (*pkey_check)(const EVP_PKEY *pk); int (*pkey_public_check)(const EVP_PKEY *pk); int (*pkey_param_check)(const EVP_PKEY *pk); + + int (*set_priv_key)(EVP_PKEY *pk, const unsigned char *private_key, + size_t len); + int (*set_pub_key)(EVP_PKEY *pk, const unsigned char *public_key, + size_t len); + int (*get_priv_key)(const EVP_PKEY *pk, unsigned char *out_private_key, + size_t *out_len); + int (*get_pub_key)(const EVP_PKEY *pk, unsigned char *out_public_key, + size_t *out_len); } /* EVP_PKEY_ASN1_METHOD */; /* Method to handle CRL access. diff --git a/lib/libcrypto/evp/evp.h b/lib/libcrypto/evp/evp.h index ec6141e39ec..31c26b44440 100644 --- a/lib/libcrypto/evp/evp.h +++ b/lib/libcrypto/evp/evp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: evp.h,v 1.108 2022/11/09 19:18:08 jsing Exp $ */ +/* $OpenBSD: evp.h,v 1.109 2022/11/10 14:46:44 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -399,6 +399,17 @@ unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx); unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx); #define EVP_CIPHER_CTX_mode(e) (EVP_CIPHER_CTX_flags(e) & EVP_CIPH_MODE) +#if defined(LIBRESSL_NEXT_API) || defined(LIBRESSL_INTERNAL) +EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *engine, + const unsigned char *private_key, size_t len); +EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *engine, + const unsigned char *public_key, size_t len); +int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, + unsigned char *out_private_key, size_t *out_len); +int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, + unsigned char *out_public_key, size_t *out_len); +#endif + #define EVP_ENCODE_LENGTH(l) (((l+2)/3*4)+(l/48+1)*2+80) #define EVP_DECODE_LENGTH(l) ((l+3)/4*3+80) @@ -1414,6 +1425,7 @@ void ERR_load_EVP_strings(void); #define EVP_R_EXPECTING_A_ECDSA_KEY 141 #define EVP_R_EXPECTING_A_EC_KEY 142 #define EVP_R_FIPS_MODE_NOT_SUPPORTED 167 +#define EVP_R_GET_RAW_KEY_FAILED 182 #define EVP_R_INITIALIZATION_ERROR 134 #define EVP_R_INPUT_NOT_INITIALIZED 111 #define EVP_R_INVALID_DIGEST 152 diff --git a/lib/libcrypto/evp/evp_err.c b/lib/libcrypto/evp/evp_err.c index 4feea1aabf0..109d2d4b2e9 100644 --- a/lib/libcrypto/evp/evp_err.c +++ b/lib/libcrypto/evp/evp_err.c @@ -1,4 +1,4 @@ -/* $OpenBSD: evp_err.c,v 1.28 2022/07/12 14:42:49 kn Exp $ */ +/* $OpenBSD: evp_err.c,v 1.29 2022/11/10 14:46:44 jsing Exp $ */ /* ==================================================================== * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. * @@ -101,6 +101,7 @@ static ERR_STRING_DATA EVP_str_reasons[] = { {ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY) , "expecting a ecdsa key"}, {ERR_REASON(EVP_R_EXPECTING_A_EC_KEY) , "expecting a ec key"}, {ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"}, + {ERR_REASON(EVP_R_GET_RAW_KEY_FAILED) , "get raw key failed"}, {ERR_REASON(EVP_R_INITIALIZATION_ERROR) , "initialization error"}, {ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED) , "input not initialized"}, {ERR_REASON(EVP_R_INVALID_DIGEST) , "invalid digest"}, diff --git a/lib/libcrypto/evp/p_lib.c b/lib/libcrypto/evp/p_lib.c index b6cef5a14c3..2e0830b96eb 100644 --- a/lib/libcrypto/evp/p_lib.c +++ b/lib/libcrypto/evp/p_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: p_lib.c,v 1.29 2022/06/27 12:36:05 tb Exp $ */ +/* $OpenBSD: p_lib.c,v 1.30 2022/11/10 14:46:44 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -278,6 +278,96 @@ EVP_PKEY_set_type(EVP_PKEY *pkey, int type) return pkey_set_type(pkey, NULL, type, NULL, -1); } +EVP_PKEY * +EVP_PKEY_new_raw_private_key(int type, ENGINE *engine, + const unsigned char *private_key, size_t len) +{ + EVP_PKEY *ret; + + if ((ret = EVP_PKEY_new()) == NULL) + goto err; + + if (!pkey_set_type(ret, engine, type, NULL, -1)) + goto err; + + if (ret->ameth->set_priv_key == NULL) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + goto err; + } + if (!ret->ameth->set_priv_key(ret, private_key, len)) { + EVPerror(EVP_R_KEY_SETUP_FAILED); + goto err; + } + + return ret; + + err: + EVP_PKEY_free(ret); + + return NULL; +} + +EVP_PKEY * +EVP_PKEY_new_raw_public_key(int type, ENGINE *engine, + const unsigned char *public_key, size_t len) +{ + EVP_PKEY *ret; + + if ((ret = EVP_PKEY_new()) == NULL) + goto err; + + if (!pkey_set_type(ret, engine, type, NULL, -1)) + goto err; + + if (ret->ameth->set_pub_key == NULL) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + goto err; + } + if (!ret->ameth->set_pub_key(ret, public_key, len)) { + EVPerror(EVP_R_KEY_SETUP_FAILED); + goto err; + } + + return ret; + + err: + EVP_PKEY_free(ret); + + return NULL; +} + +int +EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, + unsigned char *out_private_key, size_t *out_len) +{ + if (pkey->ameth->get_priv_key == NULL) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (!pkey->ameth->get_priv_key(pkey, out_private_key, out_len)) { + EVPerror(EVP_R_GET_RAW_KEY_FAILED); + return 0; + } + + return 1; +} + +int +EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, + unsigned char *out_public_key, size_t *out_len) +{ + if (pkey->ameth->get_pub_key == NULL) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (!pkey->ameth->get_pub_key(pkey, out_public_key, out_len)) { + EVPerror(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) @@ -581,4 +671,3 @@ EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid) return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, 0, pnid); } - -- 2.20.1