From: JiangShui Yang yangjiangshui@h-partners.com
Chenghai Huang (15): uadk_provider: add input pointer length check for digest and cipher uadk_provider: code cleanup for provider bio uadk_provider: add length check for input pointer uadk_provider: add a timeout exit condition to the loop uadk_provider: code cleanup for uadk_provider and uadk_engine uadk_provider: add aes alg for uadk_provider in openssl3.0 uadk_engine: optimized engine update process uadk_provider: fix cipher issue when input len is 0 in decrypto update uadk_provider: fix the set ctx param function for ivlen and pad uadk_provider: fix the key and IV verification methods for cipher init uadk_provider: fix the switch condition issue of soft digest in engine uadk_provider: extract hardware initialization functions to separate functions uadk_provider: modify poll loop exit condition uadk_provider: add aes cts alg to uadk_provider in openssl3.0 uadk_provider: bugfix cipher decryption issue
Qi Tao (2): uadk_prov: fix some cleancode issues and bugs for rsa uadk_prov: fix data type conversion errors
Wenkai Lin (1): uadk_engine: remove update iv for cipher
Zhiqi Song (6): uadk_provider: add openssl ffc library function uadk_provider: reconstructing dh implementation uadk_engine/ecx: merge some similar code logic uadk_engine: fixup pubkey size used in reverse operation uadk_provider/rsa: unify function definitions with macro uadk_provider/pkey: fixup functions with the same name
src/Makefile.am | 3 +- src/uadk_async.c | 6 +- src/uadk_cipher.c | 114 +- src/uadk_digest.c | 41 +- src/uadk_ecx.c | 303 ++--- src/uadk_prov.h | 55 +- src/uadk_prov_bio.c | 19 +- src/uadk_prov_bio.h | 2 +- src/uadk_prov_cipher.c | 869 +++++++------ src/uadk_prov_dh.c | 2611 +++++++++++++++++++++------------------- src/uadk_prov_digest.c | 61 +- src/uadk_prov_ffc.c | 1888 +++++++++++++++++++++++++++++ src/uadk_prov_ffc.h | 330 +++++ src/uadk_prov_init.c | 46 +- src/uadk_prov_pkey.h | 114 +- src/uadk_prov_rsa.c | 1134 +++++++---------- src/uadk_prov_sm2.c | 94 +- 17 files changed, 5043 insertions(+), 2647 deletions(-) create mode 100644 src/uadk_prov_ffc.c create mode 100644 src/uadk_prov_ffc.h
From: Qi Tao taoqi10@huawei.com
The major issues that have been resolved are as follows: 1. In uadk_prov_rsa_init(), a deadlock occurs when a lock is returned before it is released. 2. In rsa_check_bit_useful(), the unit of the bits parameter is bit, and the unit of the flen parameter is byte. They cannot be compared directly. 3. As "new" and "export" are keywords in C++, there will be compile error with mocker UT framework. 4. In the case of an exception, the return value of the RSA_padding_xxx function is not 0. 5. Switch to software calculation only when one of the following three conditions occur, indicating that the hardware initialization fails, hardware services fail to be executed and the packet length specification is not supported.
Signed-off-by: Qi Tao taoqi10@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_prov.h | 6 +- src/uadk_prov_init.c | 5 +- src/uadk_prov_rsa.c | 750 ++++++++++++++++++++----------------------- 3 files changed, 360 insertions(+), 401 deletions(-)
diff --git a/src/uadk_prov.h b/src/uadk_prov.h index f641dce..1b8aab9 100644 --- a/src/uadk_prov.h +++ b/src/uadk_prov.h @@ -142,9 +142,9 @@ extern const OSSL_DISPATCH uadk_sm4_ecb_functions[]; extern const OSSL_DISPATCH uadk_des_ede3_cbc_functions[]; extern const OSSL_DISPATCH uadk_des_ede3_ecb_functions[];
-extern const OSSL_DISPATCH uadk_rsa_signature_functions[]; -extern const OSSL_DISPATCH uadk_rsa_keymgmt_functions[]; -extern const OSSL_DISPATCH uadk_rsa_asym_cipher_functions[]; +extern const OSSL_DISPATCH uadk_rsa_signature_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_rsa_keymgmt_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_rsa_asym_cipher_functions[FUNC_MAX_NUM];
extern const OSSL_DISPATCH uadk_dh_keymgmt_functions[]; extern const OSSL_DISPATCH uadk_dh_keyexch_functions[]; diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c index 698bbbc..34027bf 100644 --- a/src/uadk_prov_init.c +++ b/src/uadk_prov_init.c @@ -113,12 +113,13 @@ static const OSSL_ALGORITHM uadk_prov_keymgmt[] = { uadk_rsa_keymgmt_functions, "uadk RSA Keymgmt implementation." }, { "DH", UADK_DEFAULT_PROPERTIES, uadk_dh_keymgmt_functions }, { "SM2", UADK_DEFAULT_PROPERTIES, - uadk_sm2_keymgmt_functions, "uadk SM2 Keymgmt implementation."}, + uadk_sm2_keymgmt_functions, "uadk SM2 Keymgmt implementation." }, { NULL, NULL, NULL } };
static const OSSL_ALGORITHM uadk_prov_asym_cipher[] = { - { "RSA", UADK_DEFAULT_PROPERTIES, uadk_rsa_asym_cipher_functions }, + { "RSA", UADK_DEFAULT_PROPERTIES, + uadk_rsa_asym_cipher_functions, "uadk RSA asym cipher implementation." }, { "SM2", UADK_DEFAULT_PROPERTIES, uadk_sm2_asym_cipher_functions, "uadk SM2 asym cipher implementation." }, { NULL, NULL, NULL } diff --git a/src/uadk_prov_rsa.c b/src/uadk_prov_rsa.c index bdec28f..03456fb 100644 --- a/src/uadk_prov_rsa.c +++ b/src/uadk_prov_rsa.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 /* * Copyright 2023-2024 Huawei Technologies Co.,Ltd. All rights reserved. * Copyright 2023-2024 Linaro ltd. @@ -48,7 +49,6 @@ #define BN_ERR (-1) #define BN_REDO (-2) #define GET_ERR_FINISH 0 -#define SOFT 2 #define UNUSED(x) ((void)(x)) #define UADK_E_SUCCESS 1 #define UADK_E_FAIL 0 @@ -62,6 +62,7 @@ #define GENCB_NEXT 2 #define GENCB_RETRY 3 #define PRIME_CHECK_BIT_NUM 4 +#define SOFT_SWITCH 0
struct bignum_st { BN_ULONG *d; @@ -235,6 +236,7 @@ struct rsa_st {
typedef struct rsa_st RSA;
+/* EVP_SIGNATURE */ struct evp_signature_st { int name_id; char *type_name; @@ -269,8 +271,9 @@ struct evp_signature_st { OSSL_FUNC_signature_gettable_ctx_md_params_fn *gettable_ctx_md_params; OSSL_FUNC_signature_set_ctx_md_params_fn *set_ctx_md_params; OSSL_FUNC_signature_settable_ctx_md_params_fn *settable_ctx_md_params; -} /* EVP_SIGNATURE */; +};
+/* EVP_ASYM_CIPHER */ struct evp_asym_cipher_st { int name_id; char *type_name; @@ -291,7 +294,7 @@ struct evp_asym_cipher_st { OSSL_FUNC_asym_cipher_gettable_ctx_params_fn *gettable_ctx_params; OSSL_FUNC_asym_cipher_set_ctx_params_fn *set_ctx_params; OSSL_FUNC_asym_cipher_settable_ctx_params_fn *settable_ctx_params; -} /* EVP_ASYM_CIPHER */; +};
typedef struct{ int id; /* libcrypto internal */ @@ -306,7 +309,7 @@ typedef struct{ # endif
/* Constructor(s), destructor, information */ - OSSL_FUNC_keymgmt_new_fn *new; + OSSL_FUNC_keymgmt_new_fn *new_fun; OSSL_FUNC_keymgmt_free_fn *free; OSSL_FUNC_keymgmt_get_params_fn *get_params; OSSL_FUNC_keymgmt_gettable_params_fn *gettable_params; @@ -334,7 +337,7 @@ typedef struct{ # if OPENSSL_VERSION_NUMBER >= 0x30200000 OSSL_FUNC_keymgmt_import_types_ex_fn *import_types_ex; # endif - OSSL_FUNC_keymgmt_export_fn *export; + OSSL_FUNC_keymgmt_export_fn *export_fun; OSSL_FUNC_keymgmt_export_types_fn *export_types; # if OPENSSL_VERSION_NUMBER >= 0x30200000 OSSL_FUNC_keymgmt_export_types_ex_fn *export_types_ex; @@ -432,13 +435,14 @@ static void uadk_rsa_get0_key(const RSA *r, const BIGNUM **n,
static int uadk_rsa_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) { - /* If the fields n and e in r are NULL, the corresponding input + /* + * If the fields n and e in r are NULL, the corresponding input * parameters MUST be non-NULL for n and e. d may be * left NULL (in case only the public key is used). */ if ((r->n == NULL && n == NULL) || (r->e == NULL && e == NULL)) - return 0; + return UADK_E_FAIL;
if (n != NULL) { BN_free(r->n); @@ -455,7 +459,7 @@ static int uadk_rsa_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) } r->dirty_cnt++;
- return 1; + return UADK_E_SUCCESS; }
static void uadk_rsa_get0_crt_params(const RSA *r, const BIGNUM **dmp1, @@ -471,11 +475,12 @@ static void uadk_rsa_get0_crt_params(const RSA *r, const BIGNUM **dmp1,
static int uadk_rsa_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) { - /* If the fields p and q in r are NULL, the corresponding input + /* + * If the fields p and q in r are NULL, the corresponding input * parameters MUST be non-NULL. */ if ((r->p == NULL && p == NULL) || (r->q == NULL && q == NULL)) - return 0; + return UADK_E_FAIL;
if (p != NULL) { BN_clear_free(r->p); @@ -491,18 +496,19 @@ static int uadk_rsa_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
r->dirty_cnt++;
- return 1; + return UADK_E_SUCCESS; }
static int uadk_rsa_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) { - /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input + /* + * If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input * parameters MUST be non-NULL. */ if ((r->dmp1 == NULL && dmp1 == NULL) || (r->dmq1 == NULL && dmq1 == NULL) || (r->iqmp == NULL && iqmp == NULL)) - return 0; + return UADK_E_FAIL;
if (dmp1 != NULL) { BN_clear_free(r->dmp1); @@ -524,7 +530,7 @@ static int uadk_rsa_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *
r->dirty_cnt++;
- return 1; + return UADK_E_SUCCESS; }
static int uadk_rsa_bits(const RSA *r) @@ -540,15 +546,15 @@ static int uadk_rsa_size(const RSA *r) static int setup_tbuf(PROV_RSA_SIG_CTX *ctx) { if (ctx->tbuf != NULL) - return 1; + return UADK_E_SUCCESS;
ctx->tbuf = OPENSSL_malloc(uadk_rsa_size(ctx->rsa)); if (ctx->tbuf == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); - return 0; + return UADK_E_FAIL; }
- return 1; + return UADK_E_SUCCESS; }
static void clean_tbuf(PROV_RSA_SIG_CTX *ctx) @@ -566,8 +572,8 @@ static void free_tbuf(PROV_RSA_SIG_CTX *ctx)
static int rsa_check_bit_useful(const int bits, int flen) { - if (flen > bits) - return SOFT; + if (flen > (bits >> BIT_BYTES_SHIFT)) + return UADK_DO_SOFT;
if (bits < RSA_MIN_MODULUS_BITS) return UADK_E_FAIL; @@ -581,9 +587,9 @@ static int rsa_check_bit_useful(const int bits, int flen) case OPENSSLRSA7680BITS: case OPENSSLRSA15360BITS: case RSA_MIN_MODULUS_BITS: - return SOFT; + return UADK_DO_SOFT; default: - return SOFT; + return UADK_DO_SOFT; } }
@@ -644,12 +650,12 @@ static int check_rsa_prime_sufficient(int *num, const int *bitsr, if (*num < RSA_MAX_PRIME_NUM) *bitse -= bitsr[*num]; else - return -1; + return BN_ERR;
ret = BN_GENCB_call(cb, GENCB_NEXT, *n); (*n)++; if (!ret) - return -1; + return BN_ERR;
if (retries == PRIME_RETRY_COUNT) { *num = -1; @@ -717,7 +723,7 @@ static int check_rsa_prime_useful(int * const n, struct rsa_prime_param *param, * r2 = prime - 1. */ if (!BN_sub(param->r2, param->prime, BN_value_one())) - return -1; + return BN_ERR; ERR_set_mark(); BN_set_flags(param->r2, BN_FLG_CONSTTIME); /* @@ -930,21 +936,21 @@ static int add_rsa_pubenc_padding(int flen, const unsigned char *from, }
static int check_rsa_pridec_padding(unsigned char *to, int num, - const unsigned char *buf, int len, + const unsigned char *buf, int flen, int padding) { int ret;
switch (padding) { case RSA_PKCS1_PADDING: - ret = RSA_padding_check_PKCS1_type_2(to, num, buf, len, num); - if (!ret) + ret = RSA_padding_check_PKCS1_type_2(to, num, buf, flen, num); + if (ret == CHECK_PADDING_FAIL) fprintf(stderr, "RSA_PKCS1_PADDING err\n"); break; case RSA_PKCS1_OAEP_PADDING: - ret = RSA_padding_check_PKCS1_OAEP(to, num, buf, len, num, + ret = RSA_padding_check_PKCS1_OAEP(to, num, buf, flen, num, NULL, 0); - if (!ret) + if (ret == CHECK_PADDING_FAIL) fprintf(stderr, "RSA_PKCS1_OAEP_PADDING err\n"); break; default: @@ -971,7 +977,7 @@ static int add_rsa_prienc_padding(int flen, const unsigned char *from, break; case RSA_X931_PADDING: ret = RSA_padding_add_X931(to_buf, tlen, from, flen); - if (!ret) + if (ret == -1) fprintf(stderr, "RSA_X931_PADDING err\n"); break; default: @@ -992,12 +998,12 @@ static int check_rsa_pubdec_padding(unsigned char *to, int num, switch (padding) { case RSA_PKCS1_PADDING: ret = RSA_padding_check_PKCS1_type_1(to, num, buf, len, num); - if (!ret) + if (ret == CHECK_PADDING_FAIL) fprintf(stderr, "RSA_PKCS1_PADDING err\n"); break; case RSA_X931_PADDING: ret = RSA_padding_check_X931(to, num, buf, len, num); - if (!ret) + if (ret == CHECK_PADDING_FAIL) fprintf(stderr, "RSA_X931_PADDING err\n"); break; default: @@ -1076,15 +1082,24 @@ static int uadk_rsa_env_poll(void *ctx) return -ETIMEDOUT; }
+static void uadk_rsa_mutex_infork(void) +{ + /* Release the replication lock of the child process */ + pthread_mutex_unlock(&rsa_mutex); +} + static int uadk_prov_rsa_init(void) { int ret;
+ pthread_atfork(NULL, NULL, uadk_rsa_mutex_infork); pthread_mutex_lock(&rsa_mutex); if (g_rsa_prov.pid != getpid()) { - ret = wd_rsa_init2("rsa", 0, 0); - if (unlikely(ret)) + ret = wd_rsa_init2("rsa", SCHED_POLICY_RR, TASK_MIX); + if (unlikely(ret)) { + pthread_mutex_unlock(&rsa_mutex); return ret; + } g_rsa_prov.pid = getpid(); async_register_poll_fn(ASYNC_TASK_RSA, uadk_rsa_env_poll); } @@ -1601,12 +1616,12 @@ static int uadk_prov_rsa_keygen(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb) int ret;
ret = rsa_check_bit_useful(bits, 0); - if (!ret || ret == SOFT) - return UADK_DO_SOFT; + if (ret != UADK_E_SUCCESS) + return ret;
ret = rsa_keygen_param_alloc(&keygen_param, &bn_param, &key_pair, &bn_ctx); if (ret == -ENOMEM) - return UADK_DO_SOFT; + return UADK_E_FAIL;
rsa_sess = rsa_get_eng_session(rsa, bits, is_crt); if (!rsa_sess) { @@ -1616,18 +1631,18 @@ static int uadk_prov_rsa_keygen(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)
ret = rsa_primes_gen(bits, e, bn_param->p, bn_param->q, cb); if (!ret) { - ret = UADK_DO_SOFT; + ret = UADK_E_FAIL; goto free_sess; }
if (!BN_copy(bn_param->e, e)) { - ret = UADK_DO_SOFT; + ret = UADK_E_FAIL; goto free_sess; }
ret = rsa_fill_keygen_data(rsa_sess, key_pair, keygen_param, bn_param); if (!ret) { - ret = UADK_DO_SOFT; + ret = UADK_E_FAIL; goto free_sess; }
@@ -1639,7 +1654,7 @@ static int uadk_prov_rsa_keygen(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)
ret = rsa_get_keygen_param(&rsa_sess->req, rsa_sess->sess, rsa, bn_param, &bn_ctx); if (!ret) - ret = UADK_DO_SOFT; + ret = UADK_E_FAIL;
free_kg_in_out: rsa_free_keygen_data(rsa_sess); @@ -1650,6 +1665,25 @@ free_keygen: return ret; }
+static int crypt_trans_bn(struct uadk_rsa_sess *rsa_sess, unsigned char *buf, int num_bytes) +{ + BIGNUM *bn = NULL; + int ret; + + bn = BN_bin2bn((const unsigned char *)rsa_sess->req.dst, + rsa_sess->req.dst_bytes, NULL); + if (!bn) + return UADK_E_FAIL; + + ret = BN_bn2binpad(bn, buf, num_bytes); + if (ret == BN_ERR) + ret = UADK_E_FAIL; + + BN_free(bn); + + return ret; +} + static int uadk_prov_rsa_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { @@ -1657,15 +1691,14 @@ static int uadk_prov_rsa_public_encrypt(int flen, const unsigned char *from, struct uadk_rsa_sess *rsa_sess = NULL; unsigned char *from_buf = NULL; int num_bytes, is_crt, ret; - BIGNUM *enc_bn = NULL;
ret = check_rsa_input_para(flen, from, to, rsa); - if (!ret || ret == SOFT) - return UADK_DO_SOFT; + if (ret != UADK_E_SUCCESS) + return ret;
ret = rsa_pkey_param_alloc(&pub_enc, NULL); if (ret == -ENOMEM) - return UADK_DO_SOFT; + return UADK_E_FAIL;
is_crt = check_rsa_is_crt(rsa);
@@ -1676,20 +1709,20 @@ static int uadk_prov_rsa_public_encrypt(int flen, const unsigned char *from, }
ret = rsa_create_pub_bn_ctx(rsa, pub_enc, &from_buf, &num_bytes); - if (ret <= 0 || flen > num_bytes) { - ret = UADK_DO_SOFT; + if (ret <= 0) { + ret = UADK_E_FAIL; goto free_sess; }
ret = add_rsa_pubenc_padding(flen, from, from_buf, num_bytes, padding); if (!ret) { - ret = UADK_DO_SOFT; + ret = UADK_E_FAIL; goto free_buf; }
ret = rsa_fill_pubkey(pub_enc, rsa_sess, from_buf, to); if (!ret) { - ret = UADK_DO_SOFT; + ret = UADK_E_FAIL; goto free_buf; }
@@ -1699,18 +1732,7 @@ static int uadk_prov_rsa_public_encrypt(int flen, const unsigned char *from, goto free_buf; }
- enc_bn = BN_bin2bn((const unsigned char *)rsa_sess->req.dst, - rsa_sess->req.dst_bytes, NULL); - if (!enc_bn) { - ret = UADK_DO_SOFT; - goto free_buf; - } - - ret = BN_bn2binpad(enc_bn, to, num_bytes); - if (ret == -1) - ret = UADK_DO_SOFT; - - BN_free(enc_bn); + ret = crypt_trans_bn(rsa_sess, to, num_bytes);
free_buf: rsa_free_pub_bn_ctx(&from_buf); @@ -1727,16 +1749,15 @@ static int uadk_prov_rsa_private_decrypt(int flen, const unsigned char *from, struct rsa_prikey_param *pri = NULL; unsigned char *from_buf = NULL; struct uadk_rsa_sess *rsa_sess; - int num_bytes, len, ret; - BIGNUM *dec_bn = NULL; + int num_bytes, ret;
ret = check_rsa_input_para(flen, from, to, rsa); - if (!ret || ret == SOFT) - return UADK_DO_SOFT; + if (ret != UADK_E_SUCCESS) + return ret;
ret = rsa_pkey_param_alloc(NULL, &pri); if (ret == -ENOMEM) - return UADK_DO_SOFT; + return UADK_E_FAIL;
pri->is_crt = check_rsa_is_crt(rsa);
@@ -1747,14 +1768,14 @@ static int uadk_prov_rsa_private_decrypt(int flen, const unsigned char *from, }
ret = rsa_create_pri_bn_ctx(rsa, pri, &from_buf, &num_bytes); - if (ret <= 0 || flen > num_bytes) { - ret = UADK_DO_SOFT; - goto free_sess; + if (ret <= 0 || flen != num_bytes) { + ret = UADK_E_FAIL; + goto free_buf; }
ret = rsa_fill_prikey(rsa, rsa_sess, pri, from_buf, to); if (!ret) { - ret = UADK_DO_SOFT; + ret = UADK_E_FAIL; goto free_buf; }
@@ -1766,25 +1787,14 @@ static int uadk_prov_rsa_private_decrypt(int flen, const unsigned char *from, goto free_buf; }
- dec_bn = BN_bin2bn((const unsigned char *)rsa_sess->req.dst, - rsa_sess->req.dst_bytes, NULL); - if (!dec_bn) { - ret = UADK_DO_SOFT; + ret = crypt_trans_bn(rsa_sess, from_buf, num_bytes); + if (!ret) goto free_buf; - }
- len = BN_bn2binpad(dec_bn, from_buf, num_bytes); - if (!len) { - ret = UADK_DO_SOFT; - goto free_dec_bn; - } - - ret = check_rsa_pridec_padding(to, num_bytes, from_buf, len, padding); + ret = check_rsa_pridec_padding(to, num_bytes, from_buf, flen, padding); if (!ret) - ret = UADK_DO_SOFT; + ret = UADK_E_FAIL;
-free_dec_bn: - BN_free(dec_bn); free_buf: rsa_free_pri_bn_ctx(&from_buf); free_sess: @@ -1794,24 +1804,55 @@ free_pkey: return ret; }
+static int sign_trans_bn(struct uadk_rsa_sess *rsa_sess, unsigned char *from_buf, + struct rsa_prikey_param *pri, int padding, + unsigned char *to, int num_bytes) +{ + BIGNUM *sign_bn = NULL; + BIGNUM *to_bn = NULL; + BIGNUM *res = NULL; + int ret; + + sign_bn = BN_bin2bn((const unsigned char *)rsa_sess->req.dst, + rsa_sess->req.dst_bytes, NULL); + if (!sign_bn) + return UADK_E_FAIL; + + to_bn = BN_bin2bn(from_buf, num_bytes, NULL); + if (!to_bn) { + BN_free(sign_bn); + + return UADK_E_FAIL; + } + + ret = rsa_get_sign_res(padding, to_bn, pri->n, sign_bn, &res); + if (!ret) { + BN_free(to_bn); + BN_free(sign_bn); + + return UADK_E_FAIL; + } + + ret = BN_bn2binpad(res, to, num_bytes); + + return ret; +} + static int uadk_prov_rsa_private_sign(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { struct uadk_rsa_sess *rsa_sess = NULL; struct rsa_prikey_param *pri = NULL; unsigned char *from_buf = NULL; - BIGNUM *sign_bn = NULL; - BIGNUM *to_bn = NULL; - BIGNUM *res = NULL; int num_bytes, ret;
ret = check_rsa_input_para(flen, from, to, rsa); - if (!ret || ret == SOFT) - return UADK_DO_SOFT; + if (ret != UADK_E_SUCCESS) + return ret;
ret = rsa_pkey_param_alloc(NULL, &pri); if (ret == -ENOMEM) - return UADK_DO_SOFT; + return UADK_E_FAIL;
pri->is_crt = check_rsa_is_crt(rsa);
@@ -1823,19 +1864,19 @@ static int uadk_prov_rsa_private_sign(int flen, const unsigned char *from,
ret = rsa_create_pri_bn_ctx(rsa, pri, &from_buf, &num_bytes); if (ret <= 0 || flen > num_bytes) { - ret = UADK_DO_SOFT; + ret = UADK_E_FAIL; goto free_sess; }
ret = add_rsa_prienc_padding(flen, from, from_buf, num_bytes, padding); if (!ret) { - ret = UADK_DO_SOFT; + ret = UADK_E_FAIL; goto free_buf; }
ret = rsa_fill_prikey(rsa, rsa_sess, pri, from_buf, to); if (!ret) { - ret = UADK_DO_SOFT; + ret = UADK_E_FAIL; goto free_buf; }
@@ -1845,31 +1886,8 @@ static int uadk_prov_rsa_private_sign(int flen, const unsigned char *from, goto free_buf; }
- sign_bn = BN_bin2bn((const unsigned char *)rsa_sess->req.dst, - rsa_sess->req.dst_bytes, NULL); - if (!sign_bn) { - ret = UADK_DO_SOFT; - goto free_buf; - } - - to_bn = BN_bin2bn(from_buf, num_bytes, NULL); - if (!to_bn) { - ret = UADK_DO_SOFT; - goto free_sign_bn; - } - - ret = rsa_get_sign_res(padding, to_bn, pri->n, sign_bn, &res); - if (!ret) { - ret = UADK_DO_SOFT; - goto free_to_bn; - } - - ret = BN_bn2binpad(res, to, num_bytes); + ret = sign_trans_bn(rsa_sess, from_buf, pri, padding, to, num_bytes);
-free_to_bn: - BN_free(to_bn); -free_sign_bn: - BN_free(sign_bn); free_buf: rsa_free_pri_bn_ctx(&from_buf); free_sess: @@ -1879,6 +1897,33 @@ free_pkey: return ret; }
+static int verify_trans_bn(struct uadk_rsa_sess *rsa_sess, unsigned char *from_buf, + int num_bytes, struct rsa_pubkey_param *pub, + int padding, int *len) +{ + BIGNUM *verify_bn = NULL; + int ret; + + verify_bn = BN_bin2bn((const unsigned char *)rsa_sess->req.dst, + rsa_sess->req.dst_bytes, NULL); + if (!verify_bn) + return UADK_E_FAIL; + + ret = rsa_get_verify_res(padding, pub->n, verify_bn); + if (!ret) { + BN_free(verify_bn); + return UADK_E_FAIL; + } + + *len = BN_bn2binpad(verify_bn, from_buf, num_bytes); + if (*len == 0) { + BN_free(verify_bn); + return UADK_E_FAIL; + } + + return ret; +} + static int uadk_prov_rsa_public_verify(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { @@ -1889,14 +1934,12 @@ static int uadk_prov_rsa_public_verify(int flen, const unsigned char *from, BIGNUM *verify_bn = NULL;
ret = check_rsa_input_para(flen, from, to, rsa); - if (!ret) - return UADK_E_FAIL; - else if (ret == SOFT) - return UADK_DO_SOFT; + if (ret != UADK_E_SUCCESS) + return ret;
ret = rsa_pkey_param_alloc(&pub, NULL); if (ret == -ENOMEM) - return UADK_DO_SOFT; + return UADK_E_FAIL;
is_crt = check_rsa_is_crt(rsa);
@@ -1908,13 +1951,13 @@ static int uadk_prov_rsa_public_verify(int flen, const unsigned char *from,
ret = rsa_create_pub_bn_ctx(rsa, pub, &from_buf, &num_bytes); if (ret <= 0 || flen > num_bytes) { - ret = UADK_DO_SOFT; + ret = UADK_E_FAIL; goto free_sess; }
ret = rsa_fill_pubkey(pub, rsa_sess, from_buf, to); if (!ret) { - ret = UADK_DO_SOFT; + ret = UADK_E_FAIL; goto free_buf; }
@@ -1925,31 +1968,12 @@ static int uadk_prov_rsa_public_verify(int flen, const unsigned char *from, goto free_buf; }
- verify_bn = BN_bin2bn((const unsigned char *)rsa_sess->req.dst, - rsa_sess->req.dst_bytes, NULL); - if (!verify_bn) { - ret = UADK_DO_SOFT; + ret = verify_trans_bn(rsa_sess, from_buf, num_bytes, pub, padding, &len); + if (!ret) goto free_buf; - } - - ret = rsa_get_verify_res(padding, pub->n, verify_bn); - if (!ret) { - ret = UADK_DO_SOFT; - goto free_verify_bn; - } - - len = BN_bn2binpad(verify_bn, from_buf, num_bytes); - if (!len) { - ret = UADK_DO_SOFT; - goto free_verify_bn; - }
ret = check_rsa_pubdec_padding(to, num_bytes, from_buf, len, padding); - if (!ret) - ret = UADK_DO_SOFT;
-free_verify_bn: - BN_free(verify_bn); free_buf: rsa_free_pub_bn_ctx(&from_buf); free_sess: @@ -2014,13 +2038,13 @@ static int uadk_rsa_asym_init(void *vprsactx, void *vrsa, break; default: ERR_raise(ERR_LIB_RSA, PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return 0; + return UADK_E_FAIL; }
if (uadk_prov_rsa_init()) priv->soft = 1;
- return 1; + return UADK_E_SUCCESS; }
static int uadk_rsa_init(void *vprsactx, void *vrsa, @@ -2029,7 +2053,7 @@ static int uadk_rsa_init(void *vprsactx, void *vrsa, PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx;
if (priv == NULL || vrsa == NULL) - return 0; + return UADK_E_FAIL;
priv->rsa = vrsa; priv->operation = operation; @@ -2047,26 +2071,26 @@ static int uadk_rsa_init(void *vprsactx, void *vrsa, break; default: ERR_raise(ERR_LIB_RSA, PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return 0; + return UADK_E_FAIL; }
if (uadk_prov_rsa_init()) priv->soft = 1;
- return 1; + return UADK_E_SUCCESS; }
static int uadk_rsa_verify_recover_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[]) { - return 1; + return UADK_E_SUCCESS; }
static int uadk_rsa_verify_recover(void *vprsactx, unsigned char *rout, size_t *routlen, size_t routsize, const unsigned char *sig, size_t siglen) { - return 1; + return UADK_E_SUCCESS; }
static int uadk_rsa_verify_init(void *vprsactx, void *vrsa, @@ -2079,84 +2103,87 @@ static int uadk_rsa_verify(void *vprsactx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen) { - typedef int (*fun_ptr)(void *vprsactx, const unsigned char *sig, - size_t siglen, const unsigned char *tbs, - size_t tbslen); PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx; size_t rslen = 0;
- if (priv->soft) + if (priv->soft && SOFT_SWITCH) goto soft; + else if (priv->soft && !SOFT_SWITCH) + return UADK_E_FAIL;
/* todo call public_verify */ if (priv->md != NULL) { /* todo */ } else { if (!setup_tbuf(priv)) - return 0; + return UADK_E_FAIL; rslen = uadk_prov_rsa_public_verify(siglen, sig, priv->tbuf, priv->rsa, priv->pad_mode); - if (rslen == UADK_DO_SOFT) - goto soft; + if (rslen == UADK_DO_SOFT || rslen == UADK_E_FAIL) { + if (rslen == UADK_DO_SOFT && SOFT_SWITCH) + goto soft; + else + return UADK_E_FAIL; + } }
if ((rslen != tbslen) || memcmp(tbs, priv->tbuf, rslen)) - return 0; + return UADK_E_FAIL;
- return 1; + return UADK_E_SUCCESS;
soft: fprintf(stderr, "switch to execute openssl software calculation.\n"); - fun_ptr fun = get_default_rsa_signature().verify; - - if (!fun) - return 0; + if (!get_default_rsa_signature().verify) + return UADK_E_FAIL;
- return fun(vprsactx, sig, siglen, tbs, tbslen); + return get_default_rsa_signature().verify(vprsactx, sig, siglen, tbs, tbslen); }
static int uadk_rsa_sign(void *vprsactx, unsigned char *sig, size_t *siglen, size_t sigsize, const unsigned char *tbs, size_t tbslen) { - typedef int (*fun_ptr)(void *vprsactx, unsigned char *sig, - size_t *siglen, size_t sigsize, - const unsigned char *tbs, size_t tbslen); PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx; size_t rsasize = uadk_rsa_size(priv->rsa); int ret;
- if (priv->soft) + if (priv->soft && SOFT_SWITCH) goto soft; + else if (priv->soft && !SOFT_SWITCH) + return UADK_E_FAIL;
if (sig == NULL) { *siglen = rsasize; - return 1; + return UADK_E_SUCCESS; }
if (sigsize < rsasize) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SIGNATURE_SIZE, "is %zu, should be at least %zu", sigsize, rsasize); - return 0; + return UADK_E_FAIL; }
ret = uadk_prov_rsa_private_sign(tbslen, tbs, sig, priv->rsa, priv->pad_mode); - if (ret == UADK_DO_SOFT) - goto soft; + if (ret == UADK_DO_SOFT || ret == UADK_E_FAIL) { + if (ret == UADK_DO_SOFT && SOFT_SWITCH) + goto soft; + else + return UADK_E_FAIL; + }
if (ret < 0) return ret;
*siglen = ret;
- return 1; + return UADK_E_SUCCESS; soft: fprintf(stderr, "switch to execute openssl software calculation.\n"); - fun_ptr fun = get_default_rsa_signature().sign; + if (!get_default_rsa_signature().sign) + return UADK_E_FAIL;
- if (!fun) - return 0; - return fun(vprsactx, sig, siglen, sigsize, tbs, tbslen); + return get_default_rsa_signature().sign(vprsactx, sig, siglen, sigsize, tbs, tbslen); }
static int uadk_rsa_sign_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[]) @@ -2227,13 +2254,13 @@ static int uadk_rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx;
if (priv == NULL) - return 0; + return UADK_E_FAIL; if (params == NULL) - return 1; + return UADK_E_SUCCESS;
/* todo */
- return 1; + return UADK_E_SUCCESS; }
static const OSSL_PARAM settable_ctx_params[] = { @@ -2265,19 +2292,13 @@ static const OSSL_PARAM *uadk_rsa_settable_ctx_params(void *vprsactx, return settable_ctx_params; }
-static int -uadk_rsa_digest_sign_init(void *vprsactx, const char *mdname, +static int uadk_rsa_digest_sign_init(void *vprsactx, const char *mdname, void *vrsa, const OSSL_PARAM params[]) { - typedef int (*fun_ptr)(void *vprsactx, const char *mdname, - void *vrsa, const OSSL_PARAM params[]); - - fun_ptr fun = get_default_rsa_signature().digest_sign_init; - - if (!fun) - return 0; + if (!get_default_rsa_signature().digest_sign_init) + return UADK_E_FAIL;
- return fun(vprsactx, mdname, vrsa, params); + return get_default_rsa_signature().digest_sign_init(vprsactx, mdname, vrsa, params); }
static int uadk_rsa_digest_signverify_update(void *vprsactx, @@ -2287,7 +2308,7 @@ static int uadk_rsa_digest_signverify_update(void *vprsactx, PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx;
if (priv == NULL || priv->mdctx == NULL) - return 0; + return UADK_E_FAIL;
return EVP_DigestUpdate(priv->mdctx, data, datalen); } @@ -2300,11 +2321,11 @@ static int uadk_rsa_digest_sign_final(void *vprsactx, unsigned char *sig, unsigned int dlen = 0;
if (priv == NULL) - return 0; + return UADK_E_FAIL; priv->flag_allow_md = 1;
if (priv->mdctx == NULL) - return 0; + return UADK_E_FAIL; /* * If sig is NULL then we're just finding out the sig size. Other fields * are ignored. Defer to rsa_sign. @@ -2315,7 +2336,7 @@ static int uadk_rsa_digest_sign_final(void *vprsactx, unsigned char *sig, * should not exceed the internal buffer size of EVP_MAX_MD_SIZE. */ if (!EVP_DigestFinal_ex(priv->mdctx, digest, &dlen)) - return 0; + return UADK_E_FAIL; }
return uadk_rsa_sign(vprsactx, sig, siglen, sigsize, @@ -2325,17 +2346,12 @@ static int uadk_rsa_digest_sign_final(void *vprsactx, unsigned char *sig, static int uadk_rsa_digest_verify_init(void *vprsactx, const char *mdname, void *vrsa, const OSSL_PARAM params[]) { - typedef int (*fun_ptr)(void *vprsactx, const char *mdname, - void *vrsa, const OSSL_PARAM params[]); - fun_ptr fun = get_default_rsa_signature().digest_verify_init; - - if (!fun) - return 0; + if (!get_default_rsa_signature().digest_verify_init) + return UADK_E_FAIL;
- return fun(vprsactx, mdname, vrsa, params); + return get_default_rsa_signature().digest_verify_init(vprsactx, mdname, vrsa, params); }
- static int uadk_rsa_digest_verify_final(void *vprsactx, const unsigned char *sig, size_t siglen) { @@ -2344,97 +2360,77 @@ static int uadk_rsa_digest_verify_final(void *vprsactx, const unsigned char *sig unsigned int dlen = 0;
if (priv == NULL) - return 0; + return UADK_E_FAIL; priv->flag_allow_md = 1; if (priv->mdctx == NULL) - return 0; + return UADK_E_FAIL;
/* * The digests used here are all known (see rsa_get_md_nid()), so they * should not exceed the internal buffer size of EVP_MAX_MD_SIZE. */ if (!EVP_DigestFinal_ex(priv->mdctx, digest, &dlen)) - return 0; + return UADK_E_FAIL;
return uadk_rsa_verify(vprsactx, sig, siglen, digest, (size_t)dlen); }
- static void *uadk_rsa_dupctx(void *vprsactx) { - typedef void* (*fun_ptr)(void *vprsactx); - fun_ptr fun = get_default_rsa_signature().dupctx; - - if (!fun) + if (!get_default_rsa_signature().dupctx) return NULL;
- return fun(vprsactx); + return get_default_rsa_signature().dupctx(vprsactx); }
static int uadk_rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) { - typedef int (*fun_ptr)(void *vprsactx, OSSL_PARAM *params); - fun_ptr fun = get_default_rsa_signature().get_ctx_params; + if (!get_default_rsa_signature().get_ctx_params) + return UADK_E_FAIL;
- if (!fun) - return 0; - return fun(vprsactx, params); + return get_default_rsa_signature().get_ctx_params(vprsactx, params); }
static const OSSL_PARAM *uadk_rsa_gettable_ctx_md_params(void *vprsactx) { - typedef const OSSL_PARAM * (*fun_ptr)(void *vprsactx); - fun_ptr fun = get_default_rsa_signature().gettable_ctx_md_params; - - if (!fun) + if (!get_default_rsa_signature().gettable_ctx_md_params) return NULL; - return fun(vprsactx); -}
+ return get_default_rsa_signature().gettable_ctx_md_params(vprsactx); +}
static int uadk_rsa_set_ctx_md_params(void *vprsactx, const OSSL_PARAM params[]) { - typedef int (*fun_ptr)(void *vprsactx, const OSSL_PARAM params[]); - fun_ptr fun = get_default_rsa_signature().set_ctx_md_params; + if (!get_default_rsa_signature().set_ctx_md_params) + return UADK_E_FAIL;
- if (!fun) - return 0; - return fun(vprsactx, params); + return get_default_rsa_signature().set_ctx_md_params(vprsactx, params); }
static const OSSL_PARAM *uadk_rsa_settable_ctx_md_params(void *vprsactx) { - typedef const OSSL_PARAM * (*fun_ptr)(void *vprsactx); - fun_ptr fun = get_default_rsa_signature().settable_ctx_md_params; - - if (!fun) + if (!get_default_rsa_signature().settable_ctx_md_params) return NULL; - return fun(vprsactx); + + return get_default_rsa_signature().settable_ctx_md_params(vprsactx); }
static const OSSL_PARAM *uadk_rsa_gettable_ctx_params(ossl_unused void *vprsactx, ossl_unused void *provctx) { - typedef const OSSL_PARAM * (*fun_ptr)(ossl_unused void *vprsactx, - ossl_unused void *provctx); - fun_ptr fun = get_default_rsa_signature().gettable_ctx_params; - - if (!fun) + if (!get_default_rsa_signature().gettable_ctx_params) return NULL;
- return fun(vprsactx, provctx); + return get_default_rsa_signature().gettable_ctx_params(vprsactx, provctx); }
static int uadk_rsa_get_ctx_md_params(void *vprsactx, OSSL_PARAM *params) { - typedef int (*fun_ptr)(void *vprsactx, OSSL_PARAM *params); - fun_ptr fun = get_default_rsa_signature().get_ctx_md_params; - - if (!fun) - return 0; + if (!get_default_rsa_signature().get_ctx_md_params) + return UADK_E_FAIL;
- return fun(vprsactx, params); + return get_default_rsa_signature().get_ctx_md_params(vprsactx, params); }
static int uadk_rsa_asym_encrypt_init(void *vprsactx, void *vrsa, @@ -2453,130 +2449,122 @@ static int uadk_rsa_asym_encrypt(void *vprsactx, unsigned char *out, size_t *outlen, size_t outsize, const unsigned char *in, size_t inlen) { - typedef int (*fun_ptr)(void *vprsactx, unsigned char *out, size_t *outlen, - size_t outsize, const unsigned char *in, size_t inlen); PROV_RSA_ASYM_CTX *priv = (PROV_RSA_ASYM_CTX *)vprsactx; + size_t len; int ret;
- if (priv->soft) + if (priv->soft && SOFT_SWITCH) goto soft; + else if (priv->soft && !SOFT_SWITCH) + return UADK_E_FAIL;
if (out == NULL) { - size_t len = uadk_rsa_size(priv->rsa); - + len = uadk_rsa_size(priv->rsa); if (len == 0) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); - return 0; + return UADK_E_FAIL; } *outlen = len; - return 1; + return UADK_E_SUCCESS; }
ret = uadk_prov_rsa_public_encrypt(inlen, in, out, priv->rsa, priv->pad_mode); - if (ret == UADK_DO_SOFT) - goto soft; - if (ret < 0) - return ret; + if (ret == UADK_DO_SOFT || ret == UADK_E_FAIL) { + if (ret == UADK_DO_SOFT && SOFT_SWITCH) + goto soft; + else + return UADK_E_FAIL; + }
*outlen = ret;
- return 1; + return UADK_E_SUCCESS; soft: fprintf(stderr, "switch to execute openssl software calculation.\n"); - fun_ptr fun = get_default_asym_cipher().encrypt; - - if (!fun) - return 0; + if (!get_default_asym_cipher().encrypt) + return UADK_E_FAIL;
- return fun(vprsactx, out, outlen, outsize, in, inlen); + return get_default_asym_cipher().encrypt(vprsactx, out, outlen, outsize, in, inlen); }
static int uadk_rsa_asym_decrypt(void *vprsactx, unsigned char *out, size_t *outlen, size_t outsize, const unsigned char *in, size_t inlen) { - typedef int (*fun_ptr)(void *vprsactx, unsigned char *out, size_t *outlen, - size_t outsize, const unsigned char *in, size_t inlen); PROV_RSA_ASYM_CTX *priv = (PROV_RSA_ASYM_CTX *)vprsactx; size_t len = uadk_rsa_size(priv->rsa); int ret;
- if (priv->soft) + if (priv->soft && SOFT_SWITCH) goto soft; + else if (priv->soft && !SOFT_SWITCH) + return UADK_E_FAIL;
if (out == NULL) { if (len == 0) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); - return 0; + return UADK_E_FAIL; } *outlen = len; - return 1; + return UADK_E_SUCCESS; }
if (outsize < len) { ERR_raise(ERR_LIB_PROV, PROV_R_BAD_LENGTH); - return 0; + return UADK_E_FAIL; }
ret = uadk_prov_rsa_private_decrypt(inlen, in, out, priv->rsa, priv->pad_mode); - if (ret == UADK_DO_SOFT) - goto soft; - if (ret < 0) - return ret; + if (ret == UADK_DO_SOFT || ret == UADK_E_FAIL) { + if (ret == UADK_DO_SOFT && SOFT_SWITCH) + goto soft; + else + return UADK_E_FAIL; + }
*outlen = ret;
- return 1; + return UADK_E_SUCCESS; soft: fprintf(stderr, "switch to execute openssl software calculation.\n"); - fun_ptr fun = get_default_asym_cipher().decrypt; - - if (!fun) - return 0; + if (!get_default_asym_cipher().decrypt) + return UADK_E_FAIL;
- return fun(vprsactx, out, outlen, outsize, in, inlen); + return get_default_asym_cipher().decrypt(vprsactx, out, outlen, outsize, in, inlen); }
static int uadk_rsa_asym_get_ctx_params(void *vprsactx, OSSL_PARAM *params) { - typedef int (*fun_ptr)(void *vprsactx, OSSL_PARAM *params); - fun_ptr fun = get_default_asym_cipher().get_ctx_params; + if (!get_default_asym_cipher().get_ctx_params) + return UADK_E_FAIL;
- if (!fun) - return 0; - return fun(vprsactx, params); + return get_default_asym_cipher().get_ctx_params(vprsactx, params); }
static const OSSL_PARAM *uadk_rsa_asym_gettable_ctx_params(void *vprsactx, void *provctx) { - typedef const OSSL_PARAM * (*fun_ptr)(void *vprsactx, void *provctx); - fun_ptr fun = get_default_asym_cipher().gettable_ctx_params; + if (!get_default_asym_cipher().gettable_ctx_params) + return UADK_E_FAIL;
- if (!fun) - return 0; - return fun(vprsactx, provctx); + return get_default_asym_cipher().gettable_ctx_params(vprsactx, provctx); }
static int uadk_rsa_asym_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) { - typedef int (*fun_ptr)(void *vprsactx, const OSSL_PARAM *params); - fun_ptr fun = get_default_asym_cipher().set_ctx_params; + if (!get_default_asym_cipher().set_ctx_params) + return UADK_E_FAIL;
- if (!fun) - return 0; - return fun(vprsactx, params); + return get_default_asym_cipher().set_ctx_params(vprsactx, params); }
static const OSSL_PARAM *uadk_rsa_asym_settable_ctx_params(void *vprsactx, void *provctx) { - typedef const OSSL_PARAM * (*fun_ptr)(void *vprsactx, void *provctx); - fun_ptr fun = get_default_asym_cipher().settable_ctx_params; + if (!get_default_asym_cipher().settable_ctx_params) + return UADK_E_FAIL;
- if (!fun) - return 0; - return fun(vprsactx, provctx); + return get_default_asym_cipher().settable_ctx_params(vprsactx, provctx); }
static UADK_RSA_KEYMGMT get_default_keymgmt(void) @@ -2586,13 +2574,14 @@ static UADK_RSA_KEYMGMT get_default_keymgmt(void)
if (!initialized) { UADK_RSA_KEYMGMT *keymgmt = - (UADK_RSA_KEYMGMT *)EVP_KEYMGMT_fetch(NULL, "RSA", "provider=default"); + (UADK_RSA_KEYMGMT *)EVP_KEYMGMT_fetch(NULL, "RSA", + "provider=default"); if (keymgmt) { s_keymgmt = *keymgmt; EVP_KEYMGMT_free((EVP_KEYMGMT *)keymgmt); initialized = 1; } else { - fprintf(stderr, "EVP_KEYMGMT_fetch from default provider failed"); + fprintf(stderr, "EVP_KEYMGMT_fetch from default provider failed\n"); } } return s_keymgmt; @@ -2600,85 +2589,68 @@ static UADK_RSA_KEYMGMT get_default_keymgmt(void)
static void *uadk_keymgmt_rsa_newdata(void *provctx) { - typedef void* (*fun_ptr)(void *); - fun_ptr fun = get_default_keymgmt().new; - - if (!fun) + if (!get_default_keymgmt().new_fun) return NULL; - return fun(provctx); + + return get_default_keymgmt().new_fun(provctx); }
static void uadk_keymgmt_rsa_freedata(void *keydata) { - typedef void (*fun_ptr)(void *); - fun_ptr fun = get_default_keymgmt().free; - - if (!fun) + if (!get_default_keymgmt().free) return; - fun(keydata); + + get_default_keymgmt().free(keydata); }
static int uadk_keymgmt_rsa_has(const void *keydata, int selection) { - typedef int (*fun_ptr)(const void *, int); - fun_ptr fun = get_default_keymgmt().has; - - if (!fun) - return 0; + if (!get_default_keymgmt().has) + return UADK_E_FAIL;
- return fun(keydata, selection); + return get_default_keymgmt().has(keydata, selection); }
static int uadk_keymgmt_rsa_import(void *keydata, int selection, const OSSL_PARAM params[]) { - typedef int (*fun_ptr)(void *, int, const OSSL_PARAM*); - fun_ptr fun = get_default_keymgmt().import; + if (!get_default_keymgmt().import) + return UADK_E_FAIL;
- if (!fun) - return 0; - return fun(keydata, selection, params); + return get_default_keymgmt().import(keydata, selection, params); }
static const OSSL_PARAM *uadk_keymgmt_rsa_import_types(int selection) { - typedef const OSSL_PARAM* (*fun_ptr)(int); - fun_ptr fun = get_default_keymgmt().import_types; - - if (!fun) + if (!get_default_keymgmt().import_types) return NULL; - return fun(selection); + + return get_default_keymgmt().import_types(selection); }
static void *uadk_keymgmt_rsa_gen_init(void *provctx, int selection, const OSSL_PARAM params[]) { - typedef void * (*fun_ptr)(void *, int, const OSSL_PARAM *); - fun_ptr fun = get_default_keymgmt().gen_init; - - if (!fun) + if (!get_default_keymgmt().gen_init) return NULL; - return fun(provctx, selection, params); + + return get_default_keymgmt().gen_init(provctx, selection, params); }
static int uadk_keymgmt_rsa_gen_set_params(void *genctx, const OSSL_PARAM params[]) { - typedef int (*fun_ptr)(void *, const OSSL_PARAM *); - fun_ptr fun = get_default_keymgmt().gen_set_params; + if (!get_default_keymgmt().gen_set_params) + return UADK_E_FAIL;
- if (!fun) - return 0; - return fun(genctx, params); + return get_default_keymgmt().gen_set_params(genctx, params); }
static const OSSL_PARAM *uadk_keymgmt_rsa_gen_settable_params(ossl_unused void *genctx, ossl_unused void *provctx) { - typedef const OSSL_PARAM * (*fun_ptr)(void *, void *); - fun_ptr fun = get_default_keymgmt().gen_settable_params; - - if (!fun) + if (!get_default_keymgmt().gen_settable_params) return NULL; - return fun(genctx, provctx); + + return get_default_keymgmt().gen_settable_params(genctx, provctx); }
static int rsa_gencb(int p, int n, BN_GENCB *cb) @@ -2715,7 +2687,6 @@ static RSA *ossl_rsa_new_with_ctx(OSSL_LIB_CTX *libctx)
static void *uadk_keymgmt_rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) { - typedef void * (*fun_ptr)(void *, OSSL_CALLBACK *, void *); struct rsa_gen_ctx *gctx = genctx; RSA *rsa = NULL; BN_GENCB *gencb = NULL; @@ -2725,8 +2696,10 @@ static void *uadk_keymgmt_rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cba return NULL;
ret = uadk_prov_rsa_init(); - if (ret) + if (ret && SOFT_SWITCH) goto exe_soft; + else if (ret && !SOFT_SWITCH) + return NULL;
rsa = ossl_rsa_new_with_ctx(gctx->libctx); if (rsa == NULL) @@ -2739,11 +2712,16 @@ static void *uadk_keymgmt_rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cba BN_GENCB_set(gencb, rsa_gencb, genctx);
ret = uadk_prov_rsa_keygen(rsa, (int)gctx->nbits, gctx->pub_exp, gencb); - if (ret == UADK_DO_SOFT) { + if (ret == UADK_DO_SOFT || ret == UADK_E_FAIL) { BN_GENCB_free(gencb); uadk_keymgmt_rsa_freedata(rsa); - goto exe_soft; + + if (ret == UADK_DO_SOFT && SOFT_SWITCH) + goto exe_soft; + else + return NULL; } + uadk_rsa_clear_flags(rsa, RSA_FLAG_TYPE_MASK); uadk_rsa_set_flags(rsa, gctx->rsa_type); BN_GENCB_free(gencb); @@ -2752,102 +2730,82 @@ static void *uadk_keymgmt_rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cba
exe_soft: fprintf(stderr, "switch to execute openssl software calculation.\n"); - fun_ptr fun = get_default_keymgmt().gen; - - if (!fun) + if (!get_default_keymgmt().gen) return NULL; - return fun(genctx, osslcb, cbarg); + return get_default_keymgmt().gen(genctx, osslcb, cbarg); }
static void uadk_keymgmt_rsa_gen_cleanup(void *genctx) { - typedef void (*fun_ptr)(void *); - fun_ptr fun = get_default_keymgmt().gen_cleanup; - - if (!fun) + if (!get_default_keymgmt().gen_cleanup) return; - fun(genctx); + + get_default_keymgmt().gen_cleanup(genctx); }
static void *uadk_keymgmt_rsa_load(const void *reference, size_t reference_sz) { - typedef void * (*fun_ptr)(const void *, size_t); - fun_ptr fun = get_default_keymgmt().load; - - if (!fun) + if (!get_default_keymgmt().load) return NULL; - return fun(reference, reference_sz); + + return get_default_keymgmt().load(reference, reference_sz); }
static int uadk_keymgmt_rsa_get_params(void *key, OSSL_PARAM params[]) { - typedef int (*fun_ptr)(void *, OSSL_PARAM *); - fun_ptr fun = get_default_keymgmt().get_params; + if (!get_default_keymgmt().get_params) + return UADK_E_FAIL;
- if (!fun) - return 0; - return fun(key, params); + return get_default_keymgmt().get_params(key, params); }
static const OSSL_PARAM *uadk_keymgmt_rsa_gettable_params(void *provctx) { - typedef const OSSL_PARAM * (*fun_ptr)(void *); - fun_ptr fun = get_default_keymgmt().gettable_params; - - if (!fun) + if (!get_default_keymgmt().gettable_params) return NULL; - return fun(provctx); + + return get_default_keymgmt().gettable_params(provctx); }
static int uadk_keymgmt_rsa_match(const void *keydata1, const void *keydata2, int selection) { - typedef int (*fun_ptr)(const void *, const void *, int); - fun_ptr fun = get_default_keymgmt().match; + if (!get_default_keymgmt().match) + return UADK_E_FAIL;
- if (!fun) - return 0; - return fun(keydata1, keydata2, selection); + return get_default_keymgmt().match(keydata1, keydata2, selection); }
static int uadk_keymgmt_rsa_validate(const void *keydata, int selection, int checktype) { - typedef int (*fun_ptr)(const void *, int, int); - fun_ptr fun = get_default_keymgmt().validate; + if (!get_default_keymgmt().validate) + return UADK_E_FAIL;
- if (!fun) - return 0; - return fun(keydata, selection, checktype); + return get_default_keymgmt().validate(keydata, selection, checktype); }
static int uadk_keymgmt_rsa_export(void *keydata, int selection, OSSL_CALLBACK *param_callback, void *cbarg) { - typedef int (*fun_ptr)(void *, int, OSSL_CALLBACK *, void *); - fun_ptr fun = get_default_keymgmt().export; + if (!get_default_keymgmt().export_fun) + return UADK_E_FAIL;
- if (!fun) - return 0; - return fun(keydata, selection, param_callback, cbarg); + return get_default_keymgmt().export_fun(keydata, selection, param_callback, cbarg); }
static const OSSL_PARAM *uadk_keymgmt_rsa_export_types(int selection) { - typedef const OSSL_PARAM * (*fun_ptr)(int); - fun_ptr fun = get_default_keymgmt().export_types; - - if (!fun) + if (!get_default_keymgmt().export_types) return NULL; - return fun(selection); + + return get_default_keymgmt().export_types(selection); }
static void *uadk_keymgmt_rsa_dup(const void *keydata_from, int selection) { - typedef void * (*fun_ptr)(const void *, int); - fun_ptr fun = get_default_keymgmt().dup; - - if (!fun) + if (!get_default_keymgmt().dup) return NULL; - return fun(keydata_from, selection); + + return get_default_keymgmt().dup(keydata_from, selection); }
const OSSL_DISPATCH uadk_rsa_keymgmt_functions[] = {
From: Chenghai Huang huangchenghai2@huawei.com
Add the input pointer length check for the digest and cipher to ensure that the input data is valid.
Signed-off-by: Chenghai Huang huangchenghai2@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_digest.c | 10 ++++++++++ src/uadk_prov_cipher.c | 28 ++++++++++++++++++++++++++-- src/uadk_prov_digest.c | 21 +++++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/src/uadk_digest.c b/src/uadk_digest.c index f460fcf..073c171 100644 --- a/src/uadk_digest.c +++ b/src/uadk_digest.c @@ -749,6 +749,11 @@ static int uadk_e_digest_update(EVP_MD_CTX *ctx, const void *data, size_t data_l return 0; }
+ if (unlikely(data_len && !data)) { + fprintf(stderr, "data to be digest is NULL.\n"); + return 0; + } + if (unlikely(priv->switch_flag == UADK_DO_SOFT)) goto soft_update;
@@ -877,6 +882,11 @@ static int uadk_e_digest_final(EVP_MD_CTX *ctx, unsigned char *digest) return 0; }
+ if (unlikely(!digest)) { + fprintf(stderr, "the output buffer is NULL.\n"); + return 0; + } + digest_set_msg_state(priv, true); priv->req.in = priv->data; priv->req.out = priv->out; diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c index fa79764..f6d1581 100644 --- a/src/uadk_prov_cipher.c +++ b/src/uadk_prov_cipher.c @@ -737,6 +737,9 @@ static int uadk_prov_cipher_cipher(void *vctx, unsigned char *out, size_t *outl, struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; int ret;
+ if (!vctx || !in || !out || !outl) + return UADK_E_FAIL; + if (inl == 0) { *outl = 0; return 1; @@ -763,6 +766,9 @@ static int uadk_prov_cipher_block_final(void *vctx, unsigned char *out, int sw_final_len = 0; int ret;
+ if (!vctx || !out || !outl) + return UADK_E_FAIL; + if (priv->sw_cipher && priv->switch_flag == UADK_DO_SOFT) { goto do_soft; @@ -845,6 +851,9 @@ static int uadk_prov_cipher_block_update(void *vctx, unsigned char *out, struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; int ret;
+ if (!vctx || !in || !out || !outl) + return UADK_E_FAIL; + if (inl == 0) { *outl = 0; return 1; @@ -869,6 +878,9 @@ static int uadk_prov_cipher_stream_update(void *vctx, unsigned char *out, struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; int ret;
+ if (!vctx || !in || !out || !outl) + return UADK_E_FAIL; + if (inl == 0) { *outl = 0; return 1; @@ -916,6 +928,9 @@ static int uadk_prov_cipher_stream_final(void *vctx, unsigned char *out, struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; int sw_final_len = 0;
+ if (!vctx || !out || !outl) + return UADK_E_FAIL; + if (priv->sw_cipher && priv->switch_flag == UADK_DO_SOFT) { if (!EVP_CipherFinal_ex(priv->sw_ctx, out, &sw_final_len)) { @@ -937,6 +952,9 @@ static int uadk_prov_cipher_einit(void *vctx, const unsigned char *key, size_t k struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; int ret;
+ if (!vctx) + return UADK_E_FAIL; + priv->req.op_type = WD_CIPHER_ENCRYPTION; priv->enc = 1;
@@ -954,6 +972,9 @@ static int uadk_prov_cipher_dinit(void *vctx, const unsigned char *key, size_t k struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; int ret;
+ if (!vctx) + return UADK_E_FAIL; + priv->req.op_type = WD_CIPHER_DECRYPTION; priv->enc = 0;
@@ -981,8 +1002,8 @@ static int uadk_prov_cipher_set_ctx_params(void *vctx, const OSSL_PARAM params[] const OSSL_PARAM *p; int ret = 1;
- if (params == NULL) - return 1; + if (!vctx) + return UADK_E_FAIL;
p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_PADDING); if (p != NULL) { @@ -1018,6 +1039,9 @@ static int uadk_prov_cipher_get_ctx_params(void *vctx, OSSL_PARAM params[]) struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; OSSL_PARAM *p;
+ if (!vctx || !params) + return UADK_E_FAIL; + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, priv->keylen)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); diff --git a/src/uadk_prov_digest.c b/src/uadk_prov_digest.c index 8cadbcf..776749b 100644 --- a/src/uadk_prov_digest.c +++ b/src/uadk_prov_digest.c @@ -413,6 +413,11 @@ do_soft_digest:
static int uadk_digest_update(struct digest_priv_ctx *priv, const void *data, size_t data_len) { + if (!priv->data) { + fprintf(stderr, "failed to do digest update, data in CTX is NULL.\n"); + return UADK_DIGEST_FAIL; + } + if (unlikely(priv->switch_flag == UADK_DO_SOFT)) goto soft_update;
@@ -505,6 +510,11 @@ static int uadk_digest_final(struct digest_priv_ctx *priv, unsigned char *digest struct async_op op; int ret;
+ if (!priv->data) { + fprintf(stderr, "failed to do digest final, data in CTX is NULL.\n"); + return UADK_DIGEST_FAIL; + } + priv->req.has_next = DIGEST_END; priv->req.in = priv->data; priv->req.out = priv->out; @@ -556,6 +566,11 @@ static int uadk_digest_digest(struct digest_priv_ctx *priv, const void *data, si struct async_op op; int ret;
+ if (!priv->data) { + fprintf(stderr, "failed to do single digest, data in CTX is NULL.\n"); + return UADK_DIGEST_FAIL; + } + priv->req.has_next = DIGEST_END; priv->req.in = priv->data; priv->req.out = priv->out; @@ -734,6 +749,12 @@ static int uadk_prov_digest(void *dctx, const unsigned char *in, size_t inl, return UADK_DIGEST_FAIL; }
+ if (inl > BUF_LEN) { + fprintf(stderr, "data len(%u) can not be processed in single digest.\n", + inl); + return UADK_DIGEST_FAIL; + } + if (outsz > 0) { ret = uadk_digest_digest(priv, in, inl, out); if (!ret)
As DH needs FFC(Finite Field Cryptography) API of OpenSSL, but the OpenSSL3.x does not place these APIs in external header file currently. Therefore, we put the related APIs in independent file of uadk_provider.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/Makefile.am | 3 +- src/uadk_prov_ffc.c | 1888 +++++++++++++++++++++++++++++++++++++++++++ src/uadk_prov_ffc.h | 330 ++++++++ 3 files changed, 2220 insertions(+), 1 deletion(-) create mode 100644 src/uadk_prov_ffc.c create mode 100644 src/uadk_prov_ffc.h
diff --git a/src/Makefile.am b/src/Makefile.am index 138f652..3c74dc9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -64,7 +64,8 @@ uadk_provider_la_SOURCES=uadk_prov_init.c uadk_async.c uadk_utils.c \ uadk_prov_digest.c uadk_prov_cipher.c \ uadk_prov_rsa.c uadk_prov_dh.c \ uadk_prov_bio.c uadk_prov_der_writer.c uadk_prov_packet.c \ - uadk_prov_pkey.c uadk_prov_sm2.c + uadk_prov_pkey.c uadk_prov_sm2.c \ + uadk_prov_ffc.c
uadk_provider_la_LDFLAGS=-module -version-number $(VERSION) uadk_provider_la_LIBADD=$(WD_LIBS) -lpthread diff --git a/src/uadk_prov_ffc.c b/src/uadk_prov_ffc.c new file mode 100644 index 0000000..ed5e037 --- /dev/null +++ b/src/uadk_prov_ffc.c @@ -0,0 +1,1888 @@ +// SPDX-License-Identifier: Apache-2.0 +/* + * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +#include <string.h> +#include <openssl/bn.h> +#include <openssl/dsaerr.h> +#include <openssl/err.h> +#include <openssl/rand.h> +#include <openssl/sha.h> +#include "uadk_prov_ffc.h" + +#if BN_BITS2 == 64 +#define BN_DEF(lo, hi) (BN_ULONG)hi << 32 | lo +#else +#define BN_DEF(lo, hi) lo, hi +#endif + +/* DH parameters from RFC3526 */ + +# ifndef FIPS_MODULE +/* + * "1536-bit MODP Group" from RFC3526, Section 2. + * + * The prime is: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 } + * + * RFC3526 specifies a generator of 2. + * RFC2412 specifies a generator of 22. + */ +static const BN_ULONG modp_1536_p[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0xCA237327, 0xF1746C08), + BN_DEF(0x4ABC9804, 0x670C354E), BN_DEF(0x7096966D, 0x9ED52907), + BN_DEF(0x208552BB, 0x1C62F356), BN_DEF(0xDCA3AD96, 0x83655D23), + BN_DEF(0xFD24CF5F, 0x69163FA8), BN_DEF(0x1C55D39A, 0x98DA4836), + BN_DEF(0xA163BF05, 0xC2007CB8), BN_DEF(0xECE45B3D, 0x49286651), + BN_DEF(0x7C4B1FE6, 0xAE9F2411), BN_DEF(0x5A899FA5, 0xEE386BFB), + BN_DEF(0xF406B7ED, 0x0BFF5CB6), BN_DEF(0xA637ED6B, 0xF44C42E9), + BN_DEF(0x625E7EC6, 0xE485B576), BN_DEF(0x6D51C245, 0x4FE1356D), + BN_DEF(0xF25F1437, 0x302B0A6D), BN_DEF(0xCD3A431B, 0xEF9519B3), + BN_DEF(0x8E3404DD, 0x514A0879), BN_DEF(0x3B139B22, 0x020BBEA6), + BN_DEF(0x8A67CC74, 0x29024E08), BN_DEF(0x80DC1CD1, 0xC4C6628B), + BN_DEF(0x2168C234, 0xC90FDAA2), BN_DEF(0xFFFFFFFF, 0xFFFFFFFF) +}; + +/* q = (p - 1) / 2 */ +static const BN_ULONG modp_1536_q[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0x6511B993, 0x78BA3604), + BN_DEF(0x255E4C02, 0xB3861AA7), BN_DEF(0xB84B4B36, 0xCF6A9483), + BN_DEF(0x1042A95D, 0x0E3179AB), BN_DEF(0xEE51D6CB, 0xC1B2AE91), + BN_DEF(0x7E9267AF, 0x348B1FD4), BN_DEF(0x0E2AE9CD, 0xCC6D241B), + BN_DEF(0x50B1DF82, 0xE1003E5C), BN_DEF(0xF6722D9E, 0x24943328), + BN_DEF(0xBE258FF3, 0xD74F9208), BN_DEF(0xAD44CFD2, 0xF71C35FD), + BN_DEF(0x7A035BF6, 0x85FFAE5B), BN_DEF(0xD31BF6B5, 0x7A262174), + BN_DEF(0x312F3F63, 0xF242DABB), BN_DEF(0xB6A8E122, 0xA7F09AB6), + BN_DEF(0xF92F8A1B, 0x98158536), BN_DEF(0xE69D218D, 0xF7CA8CD9), + BN_DEF(0xC71A026E, 0x28A5043C), BN_DEF(0x1D89CD91, 0x0105DF53), + BN_DEF(0x4533E63A, 0x94812704), BN_DEF(0xC06E0E68, 0x62633145), + BN_DEF(0x10B4611A, 0xE487ED51), BN_DEF(0xFFFFFFFF, 0x7FFFFFFF) +}; +# endif /* FIPS_MODULE */ + +/* + * "2048-bit MODP Group" from RFC3526, Section 3. + * + * The prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 } + * + * RFC3526 specifies a generator of 2. + */ +static const BN_ULONG modp_2048_p[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0x8AACAA68, 0x15728E5A), + BN_DEF(0x98FA0510, 0x15D22618), BN_DEF(0xEA956AE5, 0x3995497C), + BN_DEF(0x95581718, 0xDE2BCBF6), BN_DEF(0x6F4C52C9, 0xB5C55DF0), + BN_DEF(0xEC07A28F, 0x9B2783A2), BN_DEF(0x180E8603, 0xE39E772C), + BN_DEF(0x2E36CE3B, 0x32905E46), BN_DEF(0xCA18217C, 0xF1746C08), + BN_DEF(0x4ABC9804, 0x670C354E), BN_DEF(0x7096966D, 0x9ED52907), + BN_DEF(0x208552BB, 0x1C62F356), BN_DEF(0xDCA3AD96, 0x83655D23), + BN_DEF(0xFD24CF5F, 0x69163FA8), BN_DEF(0x1C55D39A, 0x98DA4836), + BN_DEF(0xA163BF05, 0xC2007CB8), BN_DEF(0xECE45B3D, 0x49286651), + BN_DEF(0x7C4B1FE6, 0xAE9F2411), BN_DEF(0x5A899FA5, 0xEE386BFB), + BN_DEF(0xF406B7ED, 0x0BFF5CB6), BN_DEF(0xA637ED6B, 0xF44C42E9), + BN_DEF(0x625E7EC6, 0xE485B576), BN_DEF(0x6D51C245, 0x4FE1356D), + BN_DEF(0xF25F1437, 0x302B0A6D), BN_DEF(0xCD3A431B, 0xEF9519B3), + BN_DEF(0x8E3404DD, 0x514A0879), BN_DEF(0x3B139B22, 0x020BBEA6), + BN_DEF(0x8A67CC74, 0x29024E08), BN_DEF(0x80DC1CD1, 0xC4C6628B), + BN_DEF(0x2168C234, 0xC90FDAA2), BN_DEF(0xFFFFFFFF, 0xFFFFFFFF) +}; +/* q = (p - 1) / 2 */ +static const BN_ULONG modp_2048_q[] = { + BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), BN_DEF(0x45565534, 0x0AB9472D), + BN_DEF(0x4C7D0288, 0x8AE9130C), BN_DEF(0x754AB572, 0x1CCAA4BE), + BN_DEF(0x4AAC0B8C, 0xEF15E5FB), BN_DEF(0x37A62964, 0xDAE2AEF8), + BN_DEF(0x7603D147, 0xCD93C1D1), BN_DEF(0x0C074301, 0xF1CF3B96), + BN_DEF(0x171B671D, 0x19482F23), BN_DEF(0x650C10BE, 0x78BA3604), + BN_DEF(0x255E4C02, 0xB3861AA7), BN_DEF(0xB84B4B36, 0xCF6A9483), + BN_DEF(0x1042A95D, 0x0E3179AB), BN_DEF(0xEE51D6CB, 0xC1B2AE91), + BN_DEF(0x7E9267AF, 0x348B1FD4), BN_DEF(0x0E2AE9CD, 0xCC6D241B), + BN_DEF(0x50B1DF82, 0xE1003E5C), BN_DEF(0xF6722D9E, 0x24943328), + BN_DEF(0xBE258FF3, 0xD74F9208), BN_DEF(0xAD44CFD2, 0xF71C35FD), + BN_DEF(0x7A035BF6, 0x85FFAE5B), BN_DEF(0xD31BF6B5, 0x7A262174), + BN_DEF(0x312F3F63, 0xF242DABB), BN_DEF(0xB6A8E122, 0xA7F09AB6), + BN_DEF(0xF92F8A1B, 0x98158536), BN_DEF(0xE69D218D, 0xF7CA8CD9), + BN_DEF(0xC71A026E, 0x28A5043C), BN_DEF(0x1D89CD91, 0x0105DF53), + BN_DEF(0x4533E63A, 0x94812704), BN_DEF(0xC06E0E68, 0x62633145), + BN_DEF(0x10B4611A, 0xE487ED51), BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), +}; + +/*- + * "3072-bit MODP Group" from RFC3526, Section 4. + * + * The prime is: 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 } + * + * RFC3526 specifies a generator of 2. + */ +static const BN_ULONG modp_3072_p[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0xA93AD2CA, 0x4B82D120), + BN_DEF(0xE0FD108E, 0x43DB5BFC), BN_DEF(0x74E5AB31, 0x08E24FA0), + BN_DEF(0xBAD946E2, 0x770988C0), BN_DEF(0x7A615D6C, 0xBBE11757), + BN_DEF(0x177B200C, 0x521F2B18), BN_DEF(0x3EC86A64, 0xD8760273), + BN_DEF(0xD98A0864, 0xF12FFA06), BN_DEF(0x1AD2EE6B, 0xCEE3D226), + BN_DEF(0x4A25619D, 0x1E8C94E0), BN_DEF(0xDB0933D7, 0xABF5AE8C), + BN_DEF(0xA6E1E4C7, 0xB3970F85), BN_DEF(0x5D060C7D, 0x8AEA7157), + BN_DEF(0x58DBEF0A, 0xECFB8504), BN_DEF(0xDF1CBA64, 0xA85521AB), + BN_DEF(0x04507A33, 0xAD33170D), BN_DEF(0x8AAAC42D, 0x15728E5A), + BN_DEF(0x98FA0510, 0x15D22618), BN_DEF(0xEA956AE5, 0x3995497C), + BN_DEF(0x95581718, 0xDE2BCBF6), BN_DEF(0x6F4C52C9, 0xB5C55DF0), + BN_DEF(0xEC07A28F, 0x9B2783A2), BN_DEF(0x180E8603, 0xE39E772C), + BN_DEF(0x2E36CE3B, 0x32905E46), BN_DEF(0xCA18217C, 0xF1746C08), + BN_DEF(0x4ABC9804, 0x670C354E), BN_DEF(0x7096966D, 0x9ED52907), + BN_DEF(0x208552BB, 0x1C62F356), BN_DEF(0xDCA3AD96, 0x83655D23), + BN_DEF(0xFD24CF5F, 0x69163FA8), BN_DEF(0x1C55D39A, 0x98DA4836), + BN_DEF(0xA163BF05, 0xC2007CB8), BN_DEF(0xECE45B3D, 0x49286651), + BN_DEF(0x7C4B1FE6, 0xAE9F2411), BN_DEF(0x5A899FA5, 0xEE386BFB), + BN_DEF(0xF406B7ED, 0x0BFF5CB6), BN_DEF(0xA637ED6B, 0xF44C42E9), + BN_DEF(0x625E7EC6, 0xE485B576), BN_DEF(0x6D51C245, 0x4FE1356D), + BN_DEF(0xF25F1437, 0x302B0A6D), BN_DEF(0xCD3A431B, 0xEF9519B3), + BN_DEF(0x8E3404DD, 0x514A0879), BN_DEF(0x3B139B22, 0x020BBEA6), + BN_DEF(0x8A67CC74, 0x29024E08), BN_DEF(0x80DC1CD1, 0xC4C6628B), + BN_DEF(0x2168C234, 0xC90FDAA2), BN_DEF(0xFFFFFFFF, 0xFFFFFFFF) +}; +/* q = (p - 1) / 2 */ +static const BN_ULONG modp_3072_q[] = { + BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), BN_DEF(0x549D6965, 0x25C16890), + BN_DEF(0x707E8847, 0xA1EDADFE), BN_DEF(0x3A72D598, 0x047127D0), + BN_DEF(0x5D6CA371, 0x3B84C460), BN_DEF(0xBD30AEB6, 0x5DF08BAB), + BN_DEF(0x0BBD9006, 0x290F958C), BN_DEF(0x9F643532, 0x6C3B0139), + BN_DEF(0x6CC50432, 0xF897FD03), BN_DEF(0x0D697735, 0xE771E913), + BN_DEF(0x2512B0CE, 0x8F464A70), BN_DEF(0x6D8499EB, 0xD5FAD746), + BN_DEF(0xD370F263, 0xD9CB87C2), BN_DEF(0xAE83063E, 0x457538AB), + BN_DEF(0x2C6DF785, 0x767DC282), BN_DEF(0xEF8E5D32, 0xD42A90D5), + BN_DEF(0x82283D19, 0xD6998B86), BN_DEF(0x45556216, 0x0AB9472D), + BN_DEF(0x4C7D0288, 0x8AE9130C), BN_DEF(0x754AB572, 0x1CCAA4BE), + BN_DEF(0x4AAC0B8C, 0xEF15E5FB), BN_DEF(0x37A62964, 0xDAE2AEF8), + BN_DEF(0x7603D147, 0xCD93C1D1), BN_DEF(0x0C074301, 0xF1CF3B96), + BN_DEF(0x171B671D, 0x19482F23), BN_DEF(0x650C10BE, 0x78BA3604), + BN_DEF(0x255E4C02, 0xB3861AA7), BN_DEF(0xB84B4B36, 0xCF6A9483), + BN_DEF(0x1042A95D, 0x0E3179AB), BN_DEF(0xEE51D6CB, 0xC1B2AE91), + BN_DEF(0x7E9267AF, 0x348B1FD4), BN_DEF(0x0E2AE9CD, 0xCC6D241B), + BN_DEF(0x50B1DF82, 0xE1003E5C), BN_DEF(0xF6722D9E, 0x24943328), + BN_DEF(0xBE258FF3, 0xD74F9208), BN_DEF(0xAD44CFD2, 0xF71C35FD), + BN_DEF(0x7A035BF6, 0x85FFAE5B), BN_DEF(0xD31BF6B5, 0x7A262174), + BN_DEF(0x312F3F63, 0xF242DABB), BN_DEF(0xB6A8E122, 0xA7F09AB6), + BN_DEF(0xF92F8A1B, 0x98158536), BN_DEF(0xE69D218D, 0xF7CA8CD9), + BN_DEF(0xC71A026E, 0x28A5043C), BN_DEF(0x1D89CD91, 0x0105DF53), + BN_DEF(0x4533E63A, 0x94812704), BN_DEF(0xC06E0E68, 0x62633145), + BN_DEF(0x10B4611A, 0xE487ED51), BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), +}; + +/*- + * "4096-bit MODP Group" from RFC3526, Section 5. + * + * The prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 } + * + * RFC3526 specifies a generator of 2. + */ +static const BN_ULONG modp_4096_p[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0x34063199, 0x4DF435C9), + BN_DEF(0x90A6C08F, 0x86FFB7DC), BN_DEF(0x8D8FDDC1, 0x93B4EA98), + BN_DEF(0xD5B05AA9, 0xD0069127), BN_DEF(0x2170481C, 0xB81BDD76), + BN_DEF(0xCEE2D7AF, 0x1F612970), BN_DEF(0x515BE7ED, 0x233BA186), + BN_DEF(0xA090C3A2, 0x99B2964F), BN_DEF(0x4E6BC05D, 0x287C5947), + BN_DEF(0x1FBECAA6, 0x2E8EFC14), BN_DEF(0x04DE8EF9, 0xDBBBC2DB), + BN_DEF(0x2AD44CE8, 0x2583E9CA), BN_DEF(0xB6150BDA, 0x1A946834), + BN_DEF(0x6AF4E23C, 0x99C32718), BN_DEF(0xBDBA5B26, 0x88719A10), + BN_DEF(0xA787E6D7, 0x1A723C12), BN_DEF(0xA9210801, 0x4B82D120), + BN_DEF(0xE0FD108E, 0x43DB5BFC), BN_DEF(0x74E5AB31, 0x08E24FA0), + BN_DEF(0xBAD946E2, 0x770988C0), BN_DEF(0x7A615D6C, 0xBBE11757), + BN_DEF(0x177B200C, 0x521F2B18), BN_DEF(0x3EC86A64, 0xD8760273), + BN_DEF(0xD98A0864, 0xF12FFA06), BN_DEF(0x1AD2EE6B, 0xCEE3D226), + BN_DEF(0x4A25619D, 0x1E8C94E0), BN_DEF(0xDB0933D7, 0xABF5AE8C), + BN_DEF(0xA6E1E4C7, 0xB3970F85), BN_DEF(0x5D060C7D, 0x8AEA7157), + BN_DEF(0x58DBEF0A, 0xECFB8504), BN_DEF(0xDF1CBA64, 0xA85521AB), + BN_DEF(0x04507A33, 0xAD33170D), BN_DEF(0x8AAAC42D, 0x15728E5A), + BN_DEF(0x98FA0510, 0x15D22618), BN_DEF(0xEA956AE5, 0x3995497C), + BN_DEF(0x95581718, 0xDE2BCBF6), BN_DEF(0x6F4C52C9, 0xB5C55DF0), + BN_DEF(0xEC07A28F, 0x9B2783A2), BN_DEF(0x180E8603, 0xE39E772C), + BN_DEF(0x2E36CE3B, 0x32905E46), BN_DEF(0xCA18217C, 0xF1746C08), + BN_DEF(0x4ABC9804, 0x670C354E), BN_DEF(0x7096966D, 0x9ED52907), + BN_DEF(0x208552BB, 0x1C62F356), BN_DEF(0xDCA3AD96, 0x83655D23), + BN_DEF(0xFD24CF5F, 0x69163FA8), BN_DEF(0x1C55D39A, 0x98DA4836), + BN_DEF(0xA163BF05, 0xC2007CB8), BN_DEF(0xECE45B3D, 0x49286651), + BN_DEF(0x7C4B1FE6, 0xAE9F2411), BN_DEF(0x5A899FA5, 0xEE386BFB), + BN_DEF(0xF406B7ED, 0x0BFF5CB6), BN_DEF(0xA637ED6B, 0xF44C42E9), + BN_DEF(0x625E7EC6, 0xE485B576), BN_DEF(0x6D51C245, 0x4FE1356D), + BN_DEF(0xF25F1437, 0x302B0A6D), BN_DEF(0xCD3A431B, 0xEF9519B3), + BN_DEF(0x8E3404DD, 0x514A0879), BN_DEF(0x3B139B22, 0x020BBEA6), + BN_DEF(0x8A67CC74, 0x29024E08), BN_DEF(0x80DC1CD1, 0xC4C6628B), + BN_DEF(0x2168C234, 0xC90FDAA2), BN_DEF(0xFFFFFFFF, 0xFFFFFFFF) +}; +/* q = (p - 1) / 2 */ +static const BN_ULONG modp_4096_q[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0x9A0318CC, 0xA6FA1AE4), + BN_DEF(0x48536047, 0xC37FDBEE), BN_DEF(0x46C7EEE0, 0xC9DA754C), + BN_DEF(0xEAD82D54, 0x68034893), BN_DEF(0x10B8240E, 0xDC0DEEBB), + BN_DEF(0x67716BD7, 0x8FB094B8), BN_DEF(0x28ADF3F6, 0x119DD0C3), + BN_DEF(0xD04861D1, 0xCCD94B27), BN_DEF(0xA735E02E, 0x143E2CA3), + BN_DEF(0x0FDF6553, 0x97477E0A), BN_DEF(0x826F477C, 0x6DDDE16D), + BN_DEF(0x156A2674, 0x12C1F4E5), BN_DEF(0x5B0A85ED, 0x0D4A341A), + BN_DEF(0x357A711E, 0x4CE1938C), BN_DEF(0x5EDD2D93, 0xC438CD08), + BN_DEF(0x53C3F36B, 0x8D391E09), BN_DEF(0x54908400, 0x25C16890), + BN_DEF(0x707E8847, 0xA1EDADFE), BN_DEF(0x3A72D598, 0x047127D0), + BN_DEF(0x5D6CA371, 0x3B84C460), BN_DEF(0xBD30AEB6, 0x5DF08BAB), + BN_DEF(0x0BBD9006, 0x290F958C), BN_DEF(0x9F643532, 0x6C3B0139), + BN_DEF(0x6CC50432, 0xF897FD03), BN_DEF(0x0D697735, 0xE771E913), + BN_DEF(0x2512B0CE, 0x8F464A70), BN_DEF(0x6D8499EB, 0xD5FAD746), + BN_DEF(0xD370F263, 0xD9CB87C2), BN_DEF(0xAE83063E, 0x457538AB), + BN_DEF(0x2C6DF785, 0x767DC282), BN_DEF(0xEF8E5D32, 0xD42A90D5), + BN_DEF(0x82283D19, 0xD6998B86), BN_DEF(0x45556216, 0x0AB9472D), + BN_DEF(0x4C7D0288, 0x8AE9130C), BN_DEF(0x754AB572, 0x1CCAA4BE), + BN_DEF(0x4AAC0B8C, 0xEF15E5FB), BN_DEF(0x37A62964, 0xDAE2AEF8), + BN_DEF(0x7603D147, 0xCD93C1D1), BN_DEF(0x0C074301, 0xF1CF3B96), + BN_DEF(0x171B671D, 0x19482F23), BN_DEF(0x650C10BE, 0x78BA3604), + BN_DEF(0x255E4C02, 0xB3861AA7), BN_DEF(0xB84B4B36, 0xCF6A9483), + BN_DEF(0x1042A95D, 0x0E3179AB), BN_DEF(0xEE51D6CB, 0xC1B2AE91), + BN_DEF(0x7E9267AF, 0x348B1FD4), BN_DEF(0x0E2AE9CD, 0xCC6D241B), + BN_DEF(0x50B1DF82, 0xE1003E5C), BN_DEF(0xF6722D9E, 0x24943328), + BN_DEF(0xBE258FF3, 0xD74F9208), BN_DEF(0xAD44CFD2, 0xF71C35FD), + BN_DEF(0x7A035BF6, 0x85FFAE5B), BN_DEF(0xD31BF6B5, 0x7A262174), + BN_DEF(0x312F3F63, 0xF242DABB), BN_DEF(0xB6A8E122, 0xA7F09AB6), + BN_DEF(0xF92F8A1B, 0x98158536), BN_DEF(0xE69D218D, 0xF7CA8CD9), + BN_DEF(0xC71A026E, 0x28A5043C), BN_DEF(0x1D89CD91, 0x0105DF53), + BN_DEF(0x4533E63A, 0x94812704), BN_DEF(0xC06E0E68, 0x62633145), + BN_DEF(0x10B4611A, 0xE487ED51), BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), +}; + +/* DH parameters from RFC5114 */ +static const BN_ULONG dh1024_160_p[] = { + BN_DEF(0x2E4A4371, 0xDF1FB2BC), BN_DEF(0x6D4DA708, 0xE68CFDA7), + BN_DEF(0x365C1A65, 0x45BF37DF), BN_DEF(0x0DC8B4BD, 0xA151AF5F), + BN_DEF(0xF55BCCC0, 0xFAA31A4F), BN_DEF(0xE5644738, 0x4EFFD6FA), + BN_DEF(0x219A7372, 0x98488E9C), BN_DEF(0x90C4BD70, 0xACCBDD7D), + BN_DEF(0xD49B83BF, 0x24975C3C), BN_DEF(0xA9061123, 0x13ECB4AE), + BN_DEF(0x2EE652C0, 0x9838EF1E), BN_DEF(0x75A23D18, 0x6073E286), + BN_DEF(0x52D23B61, 0x9A6A9DCA), BN_DEF(0xFB06A3C6, 0x52C99FBC), + BN_DEF(0xAE5D54EC, 0xDE92DE5E), BN_DEF(0xA080E01D, 0xB10B8F96) +}; +static const BN_ULONG dh1024_160_q[] = { + BN_DEF(0x49462353, 0x64B7CB9D), BN_DEF(0x8ABA4E7D, 0x81A8DF27), + (BN_ULONG)0xF518AA87 +}; +static const BN_ULONG dh1024_160_g[] = { + BN_DEF(0x22B3B2E5, 0x855E6EEB), BN_DEF(0xF97C2A24, 0x858F4DCE), + BN_DEF(0x18D08BC8, 0x2D779D59), BN_DEF(0x8E73AFA3, 0xD662A4D1), + BN_DEF(0x69B6A28A, 0x1DBF0A01), BN_DEF(0x7A091F53, 0xA6A24C08), + BN_DEF(0x63F80A76, 0x909D0D22), BN_DEF(0xB9A92EE1, 0xD7FBD7D3), + BN_DEF(0x9E2749F4, 0x5E91547F), BN_DEF(0xB01B886A, 0x160217B4), + BN_DEF(0x5504F213, 0x777E690F), BN_DEF(0x5C41564B, 0x266FEA1E), + BN_DEF(0x14266D31, 0xD6406CFF), BN_DEF(0x58AC507F, 0xF8104DD2), + BN_DEF(0xEFB99905, 0x6765A442), BN_DEF(0xC3FD3412, 0xA4D1CBD5) +}; + +static const BN_ULONG dh2048_224_p[] = { + BN_DEF(0x0C10E64F, 0x0AC4DFFE), BN_DEF(0x4E71B81C, 0xCF9DE538), + BN_DEF(0xFFA31F71, 0x7EF363E2), BN_DEF(0x6B8E75B9, 0xE3FB73C1), + BN_DEF(0x4BA80A29, 0xC9B53DCF), BN_DEF(0x16E79763, 0x23F10B0E), + BN_DEF(0x13042E9B, 0xC52172E4), BN_DEF(0xC928B2B9, 0xBE60E69C), + BN_DEF(0xB9E587E8, 0x80CD86A1), BN_DEF(0x98C641A4, 0x315D75E1), + BN_DEF(0x44328387, 0xCDF93ACC), BN_DEF(0xDC0A486D, 0x15987D9A), + BN_DEF(0x1FD5A074, 0x7310F712), BN_DEF(0xDE31EFDC, 0x278273C7), + BN_DEF(0x415D9330, 0x1602E714), BN_DEF(0xBC8985DB, 0x81286130), + BN_DEF(0x70918836, 0xB3BF8A31), BN_DEF(0xB9C49708, 0x6A00E0A0), + BN_DEF(0x8BBC27BE, 0xC6BA0B2C), BN_DEF(0xED34DBF6, 0xC9F98D11), + BN_DEF(0xB6C12207, 0x7AD5B7D0), BN_DEF(0x55B7394B, 0xD91E8FEF), + BN_DEF(0xEFDA4DF8, 0x9037C9ED), BN_DEF(0xAD6AC212, 0x6D3F8152), + BN_DEF(0x1274A0A6, 0x1DE6B85A), BN_DEF(0x309C180E, 0xEB3D688A), + BN_DEF(0x7BA1DF15, 0xAF9A3C40), BN_DEF(0xF95A56DB, 0xE6FA141D), + BN_DEF(0xB61D0A75, 0xB54B1597), BN_DEF(0x683B9FD1, 0xA20D64E5), + BN_DEF(0x9559C51F, 0xD660FAA7), BN_DEF(0x9123A9D0, 0xAD107E1E) +}; +static const BN_ULONG dh2048_224_q[] = { + BN_DEF(0xB36371EB, 0xBF389A99), BN_DEF(0x4738CEBC, 0x1F80535A), + BN_DEF(0x99717710, 0xC58D93FE), (BN_ULONG)0x801C0D34 +}; +static const BN_ULONG dh2048_224_g[] = { + BN_DEF(0x191F2BFA, 0x84B890D3), BN_DEF(0x2A7065B3, 0x81BC087F), + BN_DEF(0xF6EC0179, 0x19C418E1), BN_DEF(0x71CFFF4C, 0x7B5A0F1C), + BN_DEF(0x9B6AA4BD, 0xEDFE72FE), BN_DEF(0x94B30269, 0x81E1BCFE), + BN_DEF(0x8D6C0191, 0x566AFBB4), BN_DEF(0x409D13CD, 0xB539CCE3), + BN_DEF(0x5F2FF381, 0x6AA21E7F), BN_DEF(0x770589EF, 0xD9E263E4), + BN_DEF(0xD19963DD, 0x10E183ED), BN_DEF(0x150B8EEB, 0xB70A8137), + BN_DEF(0x28C8F8AC, 0x051AE3D4), BN_DEF(0x0C1AB15B, 0xBB77A86F), + BN_DEF(0x16A330EF, 0x6E3025E3), BN_DEF(0xD6F83456, 0x19529A45), + BN_DEF(0x118E98D1, 0xF180EB34), BN_DEF(0x50717CBE, 0xB5F6C6B2), + BN_DEF(0xDA7460CD, 0x09939D54), BN_DEF(0x22EA1ED4, 0xE2471504), + BN_DEF(0x521BC98A, 0xB8A762D0), BN_DEF(0x5AC1348B, 0xF4D02727), + BN_DEF(0x1999024A, 0xC1766910), BN_DEF(0xA8D66AD7, 0xBE5E9001), + BN_DEF(0x620A8652, 0xC57DB17C), BN_DEF(0x00C29F52, 0xAB739D77), + BN_DEF(0xA70C4AFA, 0xDD921F01), BN_DEF(0x10B9A6F0, 0xA6824A4E), + BN_DEF(0xCFE4FFE3, 0x74866A08), BN_DEF(0x89998CAF, 0x6CDEBE7B), + BN_DEF(0x8FFDAC50, 0x9DF30B5C), BN_DEF(0x4F2D9AE3, 0xAC4032EF) +}; + +static const BN_ULONG dh2048_256_p[] = { + BN_DEF(0x1E1A1597, 0xDB094AE9), BN_DEF(0xD7EF09CA, 0x693877FA), + BN_DEF(0x6E11715F, 0x6116D227), BN_DEF(0xC198AF12, 0xA4B54330), + BN_DEF(0xD7014103, 0x75F26375), BN_DEF(0x54E710C3, 0xC3A3960A), + BN_DEF(0xBD0BE621, 0xDED4010A), BN_DEF(0x89962856, 0xC0B857F6), + BN_DEF(0x71506026, 0xB3CA3F79), BN_DEF(0xE6B486F6, 0x1CCACB83), + BN_DEF(0x14056425, 0x67E144E5), BN_DEF(0xA41825D9, 0xF6A167B5), + BN_DEF(0x96524D8E, 0x3AD83477), BN_DEF(0x51BFA4AB, 0xF13C6D9A), + BN_DEF(0x35488A0E, 0x2D525267), BN_DEF(0xCAA6B790, 0xB63ACAE1), + BN_DEF(0x81B23F76, 0x4FDB70C5), BN_DEF(0x12307F5C, 0xBC39A0BF), + BN_DEF(0xB1E59BB8, 0xB941F54E), BN_DEF(0xD45F9088, 0x6C5BFC11), + BN_DEF(0x4275BF7B, 0x22E0B1EF), BN_DEF(0x5B4758C0, 0x91F9E672), + BN_DEF(0x6BCF67ED, 0x5A8A9D30), BN_DEF(0x97517ABD, 0x209E0C64), + BN_DEF(0x830E9A7C, 0x3BF4296D), BN_DEF(0x34096FAA, 0x16C3D911), + BN_DEF(0x61B2AA30, 0xFAF7DF45), BN_DEF(0xD61957D4, 0xE00DF8F1), + BN_DEF(0x435E3B00, 0x5D2CEED4), BN_DEF(0x660DD0F2, 0x8CEEF608), + BN_DEF(0x65195999, 0xFFBBD19C), BN_DEF(0xB4B6663C, 0x87A8E61D) +}; +static const BN_ULONG dh2048_256_q[] = { + BN_DEF(0x64F5FBD3, 0xA308B0FE), BN_DEF(0x1EB3750B, 0x99B1A47D), + BN_DEF(0x40129DA2, 0xB4479976), BN_DEF(0xA709A097, 0x8CF83642) +}; +static const BN_ULONG dh2048_256_g[] = { + BN_DEF(0x6CC41659, 0x664B4C0F), BN_DEF(0xEF98C582, 0x5E2327CF), + BN_DEF(0xD4795451, 0xD647D148), BN_DEF(0x90F00EF8, 0x2F630784), + BN_DEF(0x1DB246C3, 0x184B523D), BN_DEF(0xCDC67EB6, 0xC7891428), + BN_DEF(0x0DF92B52, 0x7FD02837), BN_DEF(0x64E0EC37, 0xB3353BBB), + BN_DEF(0x57CD0915, 0xECD06E15), BN_DEF(0xDF016199, 0xB7D2BBD2), + BN_DEF(0x052588B9, 0xC8484B1E), BN_DEF(0x13D3FE14, 0xDB2A3B73), + BN_DEF(0xD182EA0A, 0xD052B985), BN_DEF(0xE83B9C80, 0xA4BD1BFF), + BN_DEF(0xFB3F2E55, 0xDFC967C1), BN_DEF(0x767164E1, 0xB5045AF2), + BN_DEF(0x6F2F9193, 0x1D14348F), BN_DEF(0x428EBC83, 0x64E67982), + BN_DEF(0x82D6ED38, 0x8AC376D2), BN_DEF(0xAAB8A862, 0x777DE62A), + BN_DEF(0xE9EC144B, 0xDDF463E5), BN_DEF(0xC77A57F2, 0x0196F931), + BN_DEF(0x41000A65, 0xA55AE313), BN_DEF(0xC28CBB18, 0x901228F8), + BN_DEF(0x7E8C6F62, 0xBC3773BF), BN_DEF(0x0C6B47B1, 0xBE3A6C1B), + BN_DEF(0xAC0BB555, 0xFF4FED4A), BN_DEF(0x77BE463F, 0x10DBC150), + BN_DEF(0x1A0BA125, 0x07F4793A), BN_DEF(0x21EF2054, 0x4CA7B18F), + BN_DEF(0x60EDBD48, 0x2E775066), BN_DEF(0x73134D0B, 0x3FB32C9B) +}; + +/* Primes from RFC 7919 */ +static const BN_ULONG ffdhe2048_p[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0x61285C97, 0x886B4238), + BN_DEF(0xC1B2EFFA, 0xC6F34A26), BN_DEF(0x7D1683B2, 0xC58EF183), + BN_DEF(0x2EC22005, 0x3BB5FCBC), BN_DEF(0x4C6FAD73, 0xC3FE3B1B), + BN_DEF(0xEEF28183, 0x8E4F1232), BN_DEF(0xE98583FF, 0x9172FE9C), + BN_DEF(0x28342F61, 0xC03404CD), BN_DEF(0xCDF7E2EC, 0x9E02FCE1), + BN_DEF(0xEE0A6D70, 0x0B07A7C8), BN_DEF(0x6372BB19, 0xAE56EDE7), + BN_DEF(0xDE394DF4, 0x1D4F42A3), BN_DEF(0x60D7F468, 0xB96ADAB7), + BN_DEF(0xB2C8E3FB, 0xD108A94B), BN_DEF(0xB324FB61, 0xBC0AB182), + BN_DEF(0x483A797A, 0x30ACCA4F), BN_DEF(0x36ADE735, 0x1DF158A1), + BN_DEF(0xF3EFE872, 0xE2A689DA), BN_DEF(0xE0E68B77, 0x984F0C70), + BN_DEF(0x7F57C935, 0xB557135E), BN_DEF(0x3DED1AF3, 0x85636555), + BN_DEF(0x5F066ED0, 0x2433F51F), BN_DEF(0xD5FD6561, 0xD3DF1ED5), + BN_DEF(0xAEC4617A, 0xF681B202), BN_DEF(0x630C75D8, 0x7D2FE363), + BN_DEF(0x249B3EF9, 0xCC939DCE), BN_DEF(0x146433FB, 0xA9E13641), + BN_DEF(0xCE2D3695, 0xD8B9C583), BN_DEF(0x273D3CF1, 0xAFDC5620), + BN_DEF(0xA2BB4A9A, 0xADF85458), BN_DEF(0xFFFFFFFF, 0xFFFFFFFF) +}; +/* q = (p - 1) / 2 */ +static const BN_ULONG ffdhe2048_q[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0x30942E4B, 0x4435A11C), + BN_DEF(0x60D977FD, 0x6379A513), BN_DEF(0xBE8B41D9, 0xE2C778C1), + BN_DEF(0x17611002, 0x9DDAFE5E), BN_DEF(0xA637D6B9, 0xE1FF1D8D), + BN_DEF(0x777940C1, 0xC7278919), BN_DEF(0x74C2C1FF, 0xC8B97F4E), + BN_DEF(0x941A17B0, 0x601A0266), BN_DEF(0xE6FBF176, 0x4F017E70), + BN_DEF(0x770536B8, 0x8583D3E4), BN_DEF(0xB1B95D8C, 0x572B76F3), + BN_DEF(0xEF1CA6FA, 0x0EA7A151), BN_DEF(0xB06BFA34, 0xDCB56D5B), + BN_DEF(0xD96471FD, 0xE88454A5), BN_DEF(0x59927DB0, 0x5E0558C1), + BN_DEF(0xA41D3CBD, 0x98566527), BN_DEF(0x9B56F39A, 0x0EF8AC50), + BN_DEF(0x79F7F439, 0xF15344ED), BN_DEF(0x707345BB, 0xCC278638), + BN_DEF(0x3FABE49A, 0xDAAB89AF), BN_DEF(0x9EF68D79, 0x42B1B2AA), + BN_DEF(0xAF833768, 0x9219FA8F), BN_DEF(0xEAFEB2B0, 0x69EF8F6A), + BN_DEF(0x576230BD, 0x7B40D901), BN_DEF(0xB1863AEC, 0xBE97F1B1), + BN_DEF(0x124D9F7C, 0xE649CEE7), BN_DEF(0x8A3219FD, 0xD4F09B20), + BN_DEF(0xE7169B4A, 0xEC5CE2C1), BN_DEF(0x139E9E78, 0x57EE2B10), + BN_DEF(0x515DA54D, 0xD6FC2A2C), BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), +}; + +static const BN_ULONG ffdhe3072_p[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0x66C62E37, 0x25E41D2B), + BN_DEF(0x3FD59D7C, 0x3C1B20EE), BN_DEF(0xFA53DDEF, 0x0ABCD06B), + BN_DEF(0xD5C4484E, 0x1DBF9A42), BN_DEF(0x9B0DEADA, 0xABC52197), + BN_DEF(0x22363A0D, 0xE86D2BC5), BN_DEF(0x9C9DF69E, 0x5CAE82AB), + BN_DEF(0x71F54BFF, 0x64F2E21E), BN_DEF(0xE2D74DD3, 0xF4FD4452), + BN_DEF(0xBC437944, 0xB4130C93), BN_DEF(0x85139270, 0xAEFE1309), + BN_DEF(0xC186D91C, 0x598CB0FA), BN_DEF(0x91F7F7EE, 0x7AD91D26), + BN_DEF(0xD6E6C907, 0x61B46FC9), BN_DEF(0xF99C0238, 0xBC34F4DE), + BN_DEF(0x6519035B, 0xDE355B3B), BN_DEF(0x611FCFDC, 0x886B4238), + BN_DEF(0xC1B2EFFA, 0xC6F34A26), BN_DEF(0x7D1683B2, 0xC58EF183), + BN_DEF(0x2EC22005, 0x3BB5FCBC), BN_DEF(0x4C6FAD73, 0xC3FE3B1B), + BN_DEF(0xEEF28183, 0x8E4F1232), BN_DEF(0xE98583FF, 0x9172FE9C), + BN_DEF(0x28342F61, 0xC03404CD), BN_DEF(0xCDF7E2EC, 0x9E02FCE1), + BN_DEF(0xEE0A6D70, 0x0B07A7C8), BN_DEF(0x6372BB19, 0xAE56EDE7), + BN_DEF(0xDE394DF4, 0x1D4F42A3), BN_DEF(0x60D7F468, 0xB96ADAB7), + BN_DEF(0xB2C8E3FB, 0xD108A94B), BN_DEF(0xB324FB61, 0xBC0AB182), + BN_DEF(0x483A797A, 0x30ACCA4F), BN_DEF(0x36ADE735, 0x1DF158A1), + BN_DEF(0xF3EFE872, 0xE2A689DA), BN_DEF(0xE0E68B77, 0x984F0C70), + BN_DEF(0x7F57C935, 0xB557135E), BN_DEF(0x3DED1AF3, 0x85636555), + BN_DEF(0x5F066ED0, 0x2433F51F), BN_DEF(0xD5FD6561, 0xD3DF1ED5), + BN_DEF(0xAEC4617A, 0xF681B202), BN_DEF(0x630C75D8, 0x7D2FE363), + BN_DEF(0x249B3EF9, 0xCC939DCE), BN_DEF(0x146433FB, 0xA9E13641), + BN_DEF(0xCE2D3695, 0xD8B9C583), BN_DEF(0x273D3CF1, 0xAFDC5620), + BN_DEF(0xA2BB4A9A, 0xADF85458), BN_DEF(0xFFFFFFFF, 0xFFFFFFFF) +}; +/* q = (p - 1) / 2 */ +static const BN_ULONG ffdhe3072_q[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0xB363171B, 0x12F20E95), + BN_DEF(0x1FEACEBE, 0x9E0D9077), BN_DEF(0xFD29EEF7, 0x055E6835), + BN_DEF(0x6AE22427, 0x0EDFCD21), BN_DEF(0xCD86F56D, 0xD5E290CB), + BN_DEF(0x911B1D06, 0x743695E2), BN_DEF(0xCE4EFB4F, 0xAE574155), + BN_DEF(0x38FAA5FF, 0xB279710F), BN_DEF(0x716BA6E9, 0x7A7EA229), + BN_DEF(0xDE21BCA2, 0x5A098649), BN_DEF(0xC289C938, 0x577F0984), + BN_DEF(0x60C36C8E, 0x2CC6587D), BN_DEF(0x48FBFBF7, 0xBD6C8E93), + BN_DEF(0xEB736483, 0x30DA37E4), BN_DEF(0x7CCE011C, 0xDE1A7A6F), + BN_DEF(0xB28C81AD, 0x6F1AAD9D), BN_DEF(0x308FE7EE, 0x4435A11C), + BN_DEF(0x60D977FD, 0x6379A513), BN_DEF(0xBE8B41D9, 0xE2C778C1), + BN_DEF(0x17611002, 0x9DDAFE5E), BN_DEF(0xA637D6B9, 0xE1FF1D8D), + BN_DEF(0x777940C1, 0xC7278919), BN_DEF(0x74C2C1FF, 0xC8B97F4E), + BN_DEF(0x941A17B0, 0x601A0266), BN_DEF(0xE6FBF176, 0x4F017E70), + BN_DEF(0x770536B8, 0x8583D3E4), BN_DEF(0xB1B95D8C, 0x572B76F3), + BN_DEF(0xEF1CA6FA, 0x0EA7A151), BN_DEF(0xB06BFA34, 0xDCB56D5B), + BN_DEF(0xD96471FD, 0xE88454A5), BN_DEF(0x59927DB0, 0x5E0558C1), + BN_DEF(0xA41D3CBD, 0x98566527), BN_DEF(0x9B56F39A, 0x0EF8AC50), + BN_DEF(0x79F7F439, 0xF15344ED), BN_DEF(0x707345BB, 0xCC278638), + BN_DEF(0x3FABE49A, 0xDAAB89AF), BN_DEF(0x9EF68D79, 0x42B1B2AA), + BN_DEF(0xAF833768, 0x9219FA8F), BN_DEF(0xEAFEB2B0, 0x69EF8F6A), + BN_DEF(0x576230BD, 0x7B40D901), BN_DEF(0xB1863AEC, 0xBE97F1B1), + BN_DEF(0x124D9F7C, 0xE649CEE7), BN_DEF(0x8A3219FD, 0xD4F09B20), + BN_DEF(0xE7169B4A, 0xEC5CE2C1), BN_DEF(0x139E9E78, 0x57EE2B10), + BN_DEF(0x515DA54D, 0xD6FC2A2C), BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), +}; + +static const BN_ULONG ffdhe4096_p[] = { + BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0x5E655F6A, 0xC68A007E), + BN_DEF(0xF44182E1, 0x4DB5A851), BN_DEF(0x7F88A46B, 0x8EC9B55A), + BN_DEF(0xCEC97DCF, 0x0A8291CD), BN_DEF(0xF98D0ACC, 0x2A4ECEA9), + BN_DEF(0x7140003C, 0x1A1DB93D), BN_DEF(0x33CB8B7A, 0x092999A3), + BN_DEF(0x71AD0038, 0x6DC778F9), BN_DEF(0x918130C4, 0xA907600A), + BN_DEF(0x2D9E6832, 0xED6A1E01), BN_DEF(0xEFB4318A, 0x7135C886), + BN_DEF(0x7E31CC7A, 0x87F55BA5), BN_DEF(0x55034004, 0x7763CF1D), + BN_DEF(0xD69F6D18, 0xAC7D5F42), BN_DEF(0xE58857B6, 0x7930E9E4), + BN_DEF(0x164DF4FB, 0x6E6F52C3), BN_DEF(0x669E1EF1, 0x25E41D2B), + BN_DEF(0x3FD59D7C, 0x3C1B20EE), BN_DEF(0xFA53DDEF, 0x0ABCD06B), + BN_DEF(0xD5C4484E, 0x1DBF9A42), BN_DEF(0x9B0DEADA, 0xABC52197), + BN_DEF(0x22363A0D, 0xE86D2BC5), BN_DEF(0x9C9DF69E, 0x5CAE82AB), + BN_DEF(0x71F54BFF, 0x64F2E21E), BN_DEF(0xE2D74DD3, 0xF4FD4452), + BN_DEF(0xBC437944, 0xB4130C93), BN_DEF(0x85139270, 0xAEFE1309), + BN_DEF(0xC186D91C, 0x598CB0FA), BN_DEF(0x91F7F7EE, 0x7AD91D26), + BN_DEF(0xD6E6C907, 0x61B46FC9), BN_DEF(0xF99C0238, 0xBC34F4DE), + BN_DEF(0x6519035B, 0xDE355B3B), BN_DEF(0x611FCFDC, 0x886B4238), + BN_DEF(0xC1B2EFFA, 0xC6F34A26), BN_DEF(0x7D1683B2, 0xC58EF183), + BN_DEF(0x2EC22005, 0x3BB5FCBC), BN_DEF(0x4C6FAD73, 0xC3FE3B1B), + BN_DEF(0xEEF28183, 0x8E4F1232), BN_DEF(0xE98583FF, 0x9172FE9C), + BN_DEF(0x28342F61, 0xC03404CD), BN_DEF(0xCDF7E2EC, 0x9E02FCE1), + BN_DEF(0xEE0A6D70, 0x0B07A7C8), BN_DEF(0x6372BB19, 0xAE56EDE7), + BN_DEF(0xDE394DF4, 0x1D4F42A3), BN_DEF(0x60D7F468, 0xB96ADAB7), + BN_DEF(0xB2C8E3FB, 0xD108A94B), BN_DEF(0xB324FB61, 0xBC0AB182), + BN_DEF(0x483A797A, 0x30ACCA4F), BN_DEF(0x36ADE735, 0x1DF158A1), + BN_DEF(0xF3EFE872, 0xE2A689DA), BN_DEF(0xE0E68B77, 0x984F0C70), + BN_DEF(0x7F57C935, 0xB557135E), BN_DEF(0x3DED1AF3, 0x85636555), + BN_DEF(0x5F066ED0, 0x2433F51F), BN_DEF(0xD5FD6561, 0xD3DF1ED5), + BN_DEF(0xAEC4617A, 0xF681B202), BN_DEF(0x630C75D8, 0x7D2FE363), + BN_DEF(0x249B3EF9, 0xCC939DCE), BN_DEF(0x146433FB, 0xA9E13641), + BN_DEF(0xCE2D3695, 0xD8B9C583), BN_DEF(0x273D3CF1, 0xAFDC5620), + BN_DEF(0xA2BB4A9A, 0xADF85458), BN_DEF(0xFFFFFFFF, 0xFFFFFFFF) +}; +/* q = (p - 1) / 2 */ +static const BN_ULONG ffdhe4096_q[] = { + BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), BN_DEF(0x2F32AFB5, 0xE345003F), + BN_DEF(0xFA20C170, 0xA6DAD428), BN_DEF(0x3FC45235, 0xC764DAAD), + BN_DEF(0xE764BEE7, 0x054148E6), BN_DEF(0xFCC68566, 0x15276754), + BN_DEF(0xB8A0001E, 0x0D0EDC9E), BN_DEF(0x99E5C5BD, 0x0494CCD1), + BN_DEF(0xB8D6801C, 0x36E3BC7C), BN_DEF(0x48C09862, 0x5483B005), + BN_DEF(0x96CF3419, 0x76B50F00), BN_DEF(0x77DA18C5, 0x389AE443), + BN_DEF(0xBF18E63D, 0x43FAADD2), BN_DEF(0xAA81A002, 0x3BB1E78E), + BN_DEF(0x6B4FB68C, 0x563EAFA1), BN_DEF(0x72C42BDB, 0xBC9874F2), + BN_DEF(0x8B26FA7D, 0xB737A961), BN_DEF(0xB34F0F78, 0x12F20E95), + BN_DEF(0x1FEACEBE, 0x9E0D9077), BN_DEF(0xFD29EEF7, 0x055E6835), + BN_DEF(0x6AE22427, 0x0EDFCD21), BN_DEF(0xCD86F56D, 0xD5E290CB), + BN_DEF(0x911B1D06, 0x743695E2), BN_DEF(0xCE4EFB4F, 0xAE574155), + BN_DEF(0x38FAA5FF, 0xB279710F), BN_DEF(0x716BA6E9, 0x7A7EA229), + BN_DEF(0xDE21BCA2, 0x5A098649), BN_DEF(0xC289C938, 0x577F0984), + BN_DEF(0x60C36C8E, 0x2CC6587D), BN_DEF(0x48FBFBF7, 0xBD6C8E93), + BN_DEF(0xEB736483, 0x30DA37E4), BN_DEF(0x7CCE011C, 0xDE1A7A6F), + BN_DEF(0xB28C81AD, 0x6F1AAD9D), BN_DEF(0x308FE7EE, 0x4435A11C), + BN_DEF(0x60D977FD, 0x6379A513), BN_DEF(0xBE8B41D9, 0xE2C778C1), + BN_DEF(0x17611002, 0x9DDAFE5E), BN_DEF(0xA637D6B9, 0xE1FF1D8D), + BN_DEF(0x777940C1, 0xC7278919), BN_DEF(0x74C2C1FF, 0xC8B97F4E), + BN_DEF(0x941A17B0, 0x601A0266), BN_DEF(0xE6FBF176, 0x4F017E70), + BN_DEF(0x770536B8, 0x8583D3E4), BN_DEF(0xB1B95D8C, 0x572B76F3), + BN_DEF(0xEF1CA6FA, 0x0EA7A151), BN_DEF(0xB06BFA34, 0xDCB56D5B), + BN_DEF(0xD96471FD, 0xE88454A5), BN_DEF(0x59927DB0, 0x5E0558C1), + BN_DEF(0xA41D3CBD, 0x98566527), BN_DEF(0x9B56F39A, 0x0EF8AC50), + BN_DEF(0x79F7F439, 0xF15344ED), BN_DEF(0x707345BB, 0xCC278638), + BN_DEF(0x3FABE49A, 0xDAAB89AF), BN_DEF(0x9EF68D79, 0x42B1B2AA), + BN_DEF(0xAF833768, 0x9219FA8F), BN_DEF(0xEAFEB2B0, 0x69EF8F6A), + BN_DEF(0x576230BD, 0x7B40D901), BN_DEF(0xB1863AEC, 0xBE97F1B1), + BN_DEF(0x124D9F7C, 0xE649CEE7), BN_DEF(0x8A3219FD, 0xD4F09B20), + BN_DEF(0xE7169B4A, 0xEC5CE2C1), BN_DEF(0x139E9E78, 0x57EE2B10), + BN_DEF(0x515DA54D, 0xD6FC2A2C), BN_DEF(0xFFFFFFFF, 0x7FFFFFFF), +}; + +make_dh_bn(dh1024_160_p); +make_dh_bn(dh1024_160_q); +make_dh_bn(dh1024_160_g); +make_dh_bn(dh2048_224_p); +make_dh_bn(dh2048_224_q); +make_dh_bn(dh2048_224_g); +make_dh_bn(dh2048_256_p); +make_dh_bn(dh2048_256_q); +make_dh_bn(dh2048_256_g); + +make_dh_bn(ffdhe2048_p); +make_dh_bn(ffdhe2048_q); +make_dh_bn(ffdhe3072_p); +make_dh_bn(ffdhe3072_q); +make_dh_bn(ffdhe4096_p); +make_dh_bn(ffdhe4096_q); + +# ifndef FIPS_MODULE +make_dh_bn(modp_1536_p); +make_dh_bn(modp_1536_q); +# endif +make_dh_bn(modp_2048_p); +make_dh_bn(modp_2048_q); +make_dh_bn(modp_3072_p); +make_dh_bn(modp_3072_q); +make_dh_bn(modp_4096_p); +make_dh_bn(modp_4096_q); + +int ossl_ffc_params_set_seed(FFC_PARAMS *params, + const unsigned char *seed, size_t seedlen) +{ + if (params == NULL) + return 0; + + if (params->seed != NULL) { + if (params->seed == seed) + return 1; + OPENSSL_free(params->seed); + } + + if (seed != NULL && seedlen > 0) { + params->seed = OPENSSL_memdup(seed, seedlen); + if (params->seed == NULL) + return 0; + params->seedlen = seedlen; + } else { + params->seed = NULL; + params->seedlen = 0; + } + + return 1; +} + +static int ffc_bn_cpy(BIGNUM **dst, const BIGNUM *src) +{ + BIGNUM *a; + + /* + * If source is read only just copy the pointer, so + * we don't have to reallocate it. + */ + if (src == NULL) { + a = NULL; + goto end; + } + + if (BN_get_flags(src, BN_FLG_STATIC_DATA) && !BN_get_flags(src, BN_FLG_MALLOCED)) { + a = (BIGNUM *)src; + goto end; + } + + a = BN_dup(src); + if (a == NULL) + return 0; + +end: + BN_clear_free(*dst); + *dst = a; + + return 1; +} + +int ossl_ffc_params_copy(FFC_PARAMS *dst, const FFC_PARAMS *src) +{ + if (src == NULL || dst == NULL) + return 0; + + if (!ffc_bn_cpy(&dst->p, src->p) + || !ffc_bn_cpy(&dst->g, src->g) + || !ffc_bn_cpy(&dst->q, src->q) + || !ffc_bn_cpy(&dst->j, src->j)) + return 0; + + OPENSSL_free(dst->seed); + dst->seedlen = src->seedlen; + if (src->seed != NULL) { + dst->seed = OPENSSL_memdup(src->seed, src->seedlen); + if (dst->seed == NULL) + return 0; + } else { + dst->seed = NULL; + } + dst->nid = src->nid; + dst->pcounter = src->pcounter; + dst->h = src->h; + dst->gindex = src->gindex; + dst->flags = src->flags; + + return 1; +} + +void ossl_ffc_params_get0_pqg(const FFC_PARAMS *d, const BIGNUM **p, + const BIGNUM **q, const BIGNUM **g) +{ + if (d == NULL) + return; + + if (p != NULL) + *p = d->p; + + if (q != NULL) + *q = d->q; + + if (g != NULL) + *g = d->g; +} + +const DH_NAMED_GROUP *ossl_ffc_uid_to_dh_named_group(int uid) +{ + size_t i; + + for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) { + if (dh_named_groups[i].uid == uid) + return &dh_named_groups[i]; + } + + return NULL; +} + + +void ossl_ffc_params_set0_pqg(FFC_PARAMS *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + if (d == NULL) + return; + + if (p != NULL && p != d->p) { + BN_free(d->p); + d->p = p; + } + + if (q != NULL && q != d->q) { + BN_free(d->q); + d->q = q; + } + + if (g != NULL && g != d->g) { + BN_free(d->g); + d->g = g; + } +} + +int ossl_ffc_named_group_set(FFC_PARAMS *ffc, const DH_NAMED_GROUP *group) +{ + if (ffc == NULL || group == NULL) + return 0; + + ossl_ffc_params_set0_pqg(ffc, (BIGNUM *)group->p, (BIGNUM *)group->q, + (BIGNUM *)group->g); + ffc->keylength = group->keylength; + + /* flush the cached nid, The DH layer is responsible for caching */ + ffc->nid = NID_undef; + + return 1; +} + +int ossl_ffc_named_group_get_uid(const DH_NAMED_GROUP *group) +{ + if (group == NULL) + return NID_undef; + + return group->uid; +} + +void ossl_ffc_params_set_gindex(FFC_PARAMS *params, int index) +{ + if (params == NULL) + return; + + params->gindex = index; +} + +void ossl_ffc_params_set_pcounter(FFC_PARAMS *params, int index) +{ + if (params == NULL) + return; + + params->pcounter = index; +} + +void ossl_ffc_params_set_h(FFC_PARAMS *params, int index) +{ + if (params == NULL) + return; + + params->h = index; +} + +int ossl_ffc_set_digest(FFC_PARAMS *params, const char *alg, const char *props) +{ + if (params == NULL) + return 0; + + params->mdname = alg; + params->mdprops = props; + + return 1; +} + +void ossl_ffc_params_enable_flags(FFC_PARAMS *params, unsigned int flags, + int enable) +{ + if (params == NULL) + return; + + if (enable) + params->flags |= flags; + else + params->flags &= ~flags; +} + +int ossl_ffc_params_cmp(const FFC_PARAMS *a, const FFC_PARAMS *b, int ignore_q) +{ + if (a == NULL || b == NULL) + return 0; + + return BN_cmp(a->p, b->p) == 0 + && BN_cmp(a->g, b->g) == 0 + && (ignore_q || BN_cmp(a->q, b->q) == 0); /* Note: q may be NULL */ +} + +void ossl_ffc_params_init(FFC_PARAMS *params) +{ + if (params == NULL) + return; + + memset(params, 0, sizeof(*params)); + params->pcounter = -1; + params->gindex = FFC_UNVERIFIABLE_GINDEX; + params->flags = FFC_PARAM_FLAG_VALIDATE_PQG; +} + +void ossl_ffc_params_cleanup(FFC_PARAMS *params) +{ + if (params == NULL) + return; + + BN_free(params->p); + BN_free(params->q); + BN_free(params->g); + BN_free(params->j); + OPENSSL_free(params->seed); + ossl_ffc_params_init(params); +} + +/* FIPS186-4 A.2.1 Unverifiable Generation of Generator g */ +static int generate_unverifiable_g(BN_CTX *ctx, BN_MONT_CTX *mont, BIGNUM *g, + BIGNUM *hbn, const BIGNUM *p, + const BIGNUM *e, const BIGNUM *pm1, + int *hret) +{ + int h = 2; + + /* Step (2): choose h (where 1 < h)*/ + if (!BN_set_word(hbn, h)) + return 0; + + for (;;) { + /* Step (3): g = h^e % p */ + if (!BN_mod_exp_mont(g, hbn, e, p, ctx, mont)) + return 0; + /* Step (4): Finish if g > 1 */ + if (BN_cmp(g, BN_value_one()) > 0) + break; + + /* Step (2) Choose any h in the range 1 < h < (p-1) */ + if (!BN_add_word(hbn, 1) || BN_cmp(hbn, pm1) >= 0) + return 0; + ++h; + } + *hret = h; + return 1; +} + +/* Generation of p is the same for FIPS 186-4 & FIPS 186-2 */ +static int generate_p(BN_CTX *ctx, const EVP_MD *evpmd, int max_counter, int n, + unsigned char *buf, size_t buf_len, const BIGNUM *q, + BIGNUM *p, int L, BN_GENCB *cb, int *counter, + int *res) +{ + unsigned char md[EVP_MAX_MD_SIZE]; + BIGNUM *W, *X, *tmp, *c, *test; + int ret = -1; + int i, j, k, r; + int mdsize; + + BN_CTX_start(ctx); + W = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + c = BN_CTX_get(ctx); + test = BN_CTX_get(ctx); + tmp = BN_CTX_get(ctx); + if (tmp == NULL) + goto err; + + if (!BN_lshift(test, BN_value_one(), L - 1)) + goto err; + + mdsize = EVP_MD_get_size(evpmd); + if (mdsize <= 0) + goto err; + + /* + * A.1.1.2 Step (10) AND + * A.1.1.2 Step (12) + * offset = 1 (this is handled below) + */ + /* + * A.1.1.2 Step (11) AND + * A.1.1.3 Step (13) + */ + for (i = 0; i <= max_counter; i++) { + if ((i != 0) && !BN_GENCB_call(cb, 0, i)) + goto err; + + BN_zero(W); + /* seed_tmp buffer contains "seed + offset - 1" */ + for (j = 0; j <= n; j++) { + /* obtain "seed + offset + j" by incrementing by 1: */ + for (k = (int)buf_len - 1; k >= 0; k--) { + buf[k]++; + if (buf[k] != 0) + break; + } + /* + * A.1.1.2 Step (11.1) AND + * A.1.1.3 Step (13.1) + * tmp = V(j) = Hash((seed + offset + j) % 2^seedlen) + */ + if (!EVP_Digest(buf, buf_len, md, NULL, evpmd, NULL) + || (BN_bin2bn(md, mdsize, tmp) == NULL) + /* + * A.1.1.2 Step (11.2) + * A.1.1.3 Step (13.2) + * W += V(j) * 2^(outlen * j) + */ + || !BN_lshift(tmp, tmp, (mdsize << 3) * j) + || !BN_add(W, W, tmp)) + goto err; + } + + /* + * A.1.1.2 Step (11.3) AND + * A.1.1.3 Step (13.3) + * X = W + 2^(L-1) where W < 2^(L-1) + */ + if (!BN_mask_bits(W, L - 1) + || !BN_copy(X, W) + || !BN_add(X, X, test) + /* + * A.1.1.2 Step (11.4) AND + * A.1.1.3 Step (13.4) + * c = X mod 2q + */ + || !BN_lshift1(tmp, q) + || !BN_mod(c, X, tmp, ctx) + /* + * A.1.1.2 Step (11.5) AND + * A.1.1.3 Step (13.5) + * p = X - (c - 1) + */ + || !BN_sub(tmp, c, BN_value_one()) + || !BN_sub(p, X, tmp)) + goto err; + + /* + * A.1.1.2 Step (11.6) AND + * A.1.1.3 Step (13.6) + * if (p < 2 ^ (L-1)) continue + * This makes sure the top bit is set. + */ + if (BN_cmp(p, test) >= 0) { + /* + * A.1.1.2 Step (11.7) AND + * A.1.1.3 Step (13.7) + * Test if p is prime + * (This also makes sure the bottom bit is set) + */ + r = BN_check_prime(p, ctx, cb); + /* A.1.1.2 Step (11.8) : Return if p is prime */ + if (r > 0) { + *counter = i; + ret = 1; /* return success */ + goto err; + } + if (r != 0) + goto err; + } + /* Step (11.9) : offset = offset + n + 1 is done auto-magically */ + } + /* No prime P found */ + ret = 0; + *res |= FFC_CHECK_P_NOT_PRIME; + +err: + BN_CTX_end(ctx); + return ret; +} + +OSSL_LIB_CTX *ossl_bn_get_libctx(BN_CTX *ctx) +{ + if (ctx == NULL) + return NULL; + return ctx->libctx; +} + +static int generate_q_fips186_2(BN_CTX *ctx, BIGNUM *q, const EVP_MD *evpmd, + unsigned char *buf, unsigned char *seed, + size_t qsize, int generate_seed, int *retm, + int *res, BN_GENCB *cb) +{ + OSSL_LIB_CTX *libctx = ossl_bn_get_libctx(ctx); + unsigned char buf2[EVP_MAX_MD_SIZE]; + unsigned char md[EVP_MAX_MD_SIZE]; + int i, r, ret = 0, m = *retm; + + /* find q */ + for (;;) { + /* step 1 */ + if (!BN_GENCB_call(cb, 0, m++)) + goto err; + + if (generate_seed && RAND_bytes_ex(libctx, seed, qsize, 0) <= 0) + goto err; + + memcpy(buf, seed, qsize); + memcpy(buf2, seed, qsize); + + /* precompute "SEED + 1" for step 7: */ + for (i = (int)qsize - 1; i >= 0; i--) { + buf[i]++; + if (buf[i] != 0) + break; + } + + /* step 2 */ + if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL)) + goto err; + if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) + goto err; + for (i = 0; i < (int)qsize; i++) + md[i] ^= buf2[i]; + + /* step 3 */ + md[0] |= 0x80; + md[qsize - 1] |= 0x01; + if (!BN_bin2bn(md, (int)qsize, q)) + goto err; + + /* step 4 */ + r = BN_check_prime(q, ctx, cb); + if (r > 0) { + /* Found a prime */ + ret = 1; + goto err; + } + if (r != 0) + goto err; /* Exit if error */ + /* Try another iteration if it wasnt prime - was in old code.. */ + generate_seed = 1; + } +err: + *retm = m; + return ret; +} + +/* + * Verify that the passed in L, N pair for DH or DSA is valid. + * Returns 0 if invalid, otherwise it returns the security strength. + */ + +#ifdef FIPS_MODULE +static int ffc_validate_LN(size_t L, size_t N, int type, int verify) +{ + if (type == FFC_PARAM_TYPE_DH) { + /* Valid DH L,N parameters from SP800-56Ar3 5.5.1 Table 1 */ + if (L == L_P_2048BITS && (N == N_Q_224BITS || N == N_Q_256BITS)) + return SECURITY_STR_112BITS; +# ifndef OPENSSL_NO_DH + ERR_raise(ERR_LIB_DH, DH_R_BAD_FFC_PARAMETERS); +# endif + } else if (type == FFC_PARAM_TYPE_DSA) { + /* Valid DSA L,N parameters from FIPS 186-4 Section 4.2 */ + /* In fips mode 1024/160 can only be used for verification */ + if (verify && L == L_P_1024BITS && N == N_Q_160BITS) + return SECURITY_STR_80BITS; + if (L == L_P_2048BITS && (N == N_Q_224BITS || N == N_Q_256BITS)) + return SECURITY_STR_112BITS; + if (L == L_P_3072BITS && N == N_Q_256BITS) + return SECURITY_STR_128BITS; +# ifndef OPENSSL_NO_DSA + ERR_raise(ERR_LIB_DSA, DSA_R_BAD_FFC_PARAMETERS); +# endif + } + + return 0; +} +#else +static int ffc_validate_LN(size_t L, size_t N, int type, int verify) +{ + if (type == FFC_PARAM_TYPE_DH) { + /* Allow legacy 1024/160 in non fips mode */ + if (L == L_P_1024BITS && N == N_Q_160BITS) + return SECURITY_STR_80BITS; + /* Valid DH L,N parameters from SP800-56Ar3 5.5.1 Table 1 */ + if (L == L_P_2048BITS && (N == N_Q_224BITS || N == N_Q_256BITS)) + return SECURITY_STR_112BITS; +# ifndef OPENSSL_NO_DH + ERR_raise(ERR_LIB_DH, DH_R_BAD_FFC_PARAMETERS); +# endif + } else if (type == FFC_PARAM_TYPE_DSA) { + if (L >= L_P_3072BITS && N >= N_Q_256BITS) + return SECURITY_STR_128BITS; + if (L >= L_P_2048BITS && N >= N_Q_224BITS) + return SECURITY_STR_112BITS; + if (L >= L_P_1024BITS && N >= N_Q_160BITS) + return SECURITY_STR_80BITS; +# ifndef OPENSSL_NO_DSA + ERR_raise(ERR_LIB_DSA, DSA_R_BAD_FFC_PARAMETERS); +# endif + } + + return 0; +} +#endif /* FIPS_MODULE */ + +int ossl_ffc_params_set_validate_params(FFC_PARAMS *params, + const unsigned char *seed, + size_t seedlen, int counter) +{ + if (!ossl_ffc_params_set_seed(params, seed, seedlen)) + return 0; + params->pcounter = counter; + return 1; +} + +static const char *default_mdname(size_t N) +{ + if (N == N_Q_160BITS) + return "SHA1"; + else if (N == N_Q_224BITS) + return "SHA-224"; + else if (N == N_Q_256BITS) + return "SHA-256"; + return NULL; +} + +/* FIPS186-4 A.2.2 Unverifiable partial validation of Generator g */ +int ossl_ffc_params_validate_unverifiable_g(BN_CTX *ctx, BN_MONT_CTX *mont, + const BIGNUM *p, const BIGNUM *q, + const BIGNUM *g, BIGNUM *tmp, + int *ret) +{ + /* + * A.2.2 Step (1) AND + * A.2.4 Step (2) + * Verify that 2 <= g <= (p - 1) + */ + if (BN_cmp(g, BN_value_one()) <= 0 || BN_cmp(g, p) >= 0) { + *ret |= FFC_ERROR_NOT_SUITABLE_GENERATOR; + return 0; + } + + /* + * A.2.2 Step (2) AND + * A.2.4 Step (3) + * Check g^q mod p = 1 + */ + if (!BN_mod_exp_mont(tmp, g, q, p, ctx, mont)) + return 0; + if (BN_cmp(tmp, BN_value_one()) != 0) { + *ret |= FFC_ERROR_NOT_SUITABLE_GENERATOR; + return 0; + } + return 1; +} + +/* Note this function is only used for verification in fips mode */ +int ossl_ffc_params_FIPS186_2_gen_verify(OSSL_LIB_CTX *libctx, + FFC_PARAMS *params, int mode, int type, + size_t L, size_t N, int *res, + BN_GENCB *cb) +{ + BIGNUM *r0, *test, *tmp, *g = NULL, *q = NULL, *p = NULL; + int counter = 0, pcounter = 0, use_random_seed; + int ok = FFC_PARAM_RET_STATUS_FAILED; + unsigned char seed[SHA256_DIGEST_LENGTH]; + unsigned char buf[SHA256_DIGEST_LENGTH]; + unsigned char *seed_in = params->seed; + size_t seed_len = params->seedlen; + int verify = (mode == FFC_PARAM_MODE_VERIFY); + unsigned int flags = verify ? params->flags : 0; + const char *def_name; + BN_MONT_CTX *mont = NULL; + BN_CTX *ctx = NULL; + EVP_MD *md = NULL; + int hret = -1; + size_t qsize; + int n = 0, m = 0; + int rv; + + *res = 0; + + if (params->mdname != NULL) { + md = EVP_MD_fetch(libctx, params->mdname, params->mdprops); + } else { + if (N == 0) { + if (L >= L_P_2048BITS) + N = TRANS_BYTES_TO_BITS(SHA256_DIGEST_LENGTH); + else + N = TRANS_BYTES_TO_BITS(SHA_DIGEST_LENGTH); + } + + def_name = default_mdname(N); + if (def_name == NULL) { + *res = FFC_CHECK_INVALID_Q_VALUE; + goto err; + } + md = EVP_MD_fetch(libctx, def_name, params->mdprops); + } + if (md == NULL) + goto err; + + if (N == 0) + N = TRANS_BYTES_TO_BITS(EVP_MD_get_size(md)); + + qsize = TRANS_BITS_TO_BYTES(N); + + /* + * The original spec allowed L = 512 + 64*j (j = 0.. 8) + * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf + * says that 512 can be used for legacy verification. + */ + if (L < L_P_512BITS) { + *res = FFC_CHECK_BAD_LN_PAIR; + goto err; + } + if (qsize != SHA_DIGEST_LENGTH + && qsize != SHA224_DIGEST_LENGTH + && qsize != SHA256_DIGEST_LENGTH) { + /* invalid q size */ + *res = FFC_CHECK_INVALID_Q_VALUE; + goto err; + } + /* Padding 'L' to the integer multiple of 64 */ + L = PADDING_LEN(L); + + if (seed_in != NULL) { + if (seed_len < qsize) { + *res = FFC_CHECK_INVALID_SEED_SIZE; + goto err; + } + /* Only consume as much seed as is expected. */ + if (seed_len > qsize) + seed_len = qsize; + memcpy(seed, seed_in, seed_len); + } + + ctx = BN_CTX_new_ex(libctx); + if (ctx == NULL) + goto err; + + BN_CTX_start(ctx); + + r0 = BN_CTX_get(ctx); + g = BN_CTX_get(ctx); + q = BN_CTX_get(ctx); + p = BN_CTX_get(ctx); + tmp = BN_CTX_get(ctx); + test = BN_CTX_get(ctx); + if (test == NULL) + goto err; + + if (!BN_lshift(test, BN_value_one(), L - 1)) + goto err; + + if (!verify) { + /* For generation: p & q must both be NULL or NON-NULL */ + if ((params->p != NULL) != (params->q != NULL)) { + *res = FFC_CHECK_INVALID_PQ; + goto err; + } + } else { + if ((flags & FFC_PARAM_FLAG_VALIDATE_PQ) != 0) { + /* Validation of p,q requires seed and counter to be valid */ + if (seed_in == NULL || params->pcounter < 0) { + *res = FFC_CHECK_MISSING_SEED_OR_COUNTER; + goto err; + } + } + if ((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0) { + /* validation of g also requires g to be set */ + if (params->g == NULL) { + *res = FFC_CHECK_INVALID_G; + goto err; + } + } + } + + if (params->p != NULL && ((flags & FFC_PARAM_FLAG_VALIDATE_PQ) == 0)) { + /* p and q already exists so only generate g */ + p = params->p; + q = params->q; + goto g_only; + /* otherwise to validate p and q */ + } + + use_random_seed = (seed_in == NULL); + for (;;) { + if (!generate_q_fips186_2(ctx, q, md, buf, seed, qsize, + use_random_seed, &m, res, cb)) + goto err; + + if (!BN_GENCB_call(cb, GENCB_NEXT, 0)) + goto err; + if (!BN_GENCB_call(cb, GENCB_RETRY, 0)) + goto err; + + /* step 6 compute the block num with digest length 160 bits */ + n = (L - 1) / 160; + counter = 4 * L - 1; /* Was 4096 */ + /* Validation requires the counter to be supplied */ + if (verify) { + if (params->pcounter > counter) { + *res = FFC_CHECK_INVALID_COUNTER; + goto err; + } + counter = params->pcounter; + } + + rv = generate_p(ctx, md, counter, n, buf, qsize, q, p, L, cb, + &pcounter, res); + if (rv > 0) + break; /* found it */ + if (rv == -1) + goto err; + /* This is what the old code did - probably not a good idea! */ + use_random_seed = 1; + } + + if (!BN_GENCB_call(cb, GENCB_NEXT, 1)) + goto err; + + if (verify) { + if (pcounter != counter) { + *res = FFC_CHECK_COUNTER_MISMATCH; + goto err; + } + + if (BN_cmp(p, params->p) != 0) { + *res = FFC_CHECK_P_MISMATCH; + goto err; + } + } + /* If validating p & q only then skip the g validation test */ + if ((flags & FFC_PARAM_FLAG_VALIDATE_PQG) == FFC_PARAM_FLAG_VALIDATE_PQ) + goto pass; + +g_only: + mont = BN_MONT_CTX_new(); + if (mont == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, p, ctx)) + goto err; + + if (!verify) { + /* We now need to generate g */ + /* set test = p - 1 */ + if (!BN_sub(test, p, BN_value_one())) + goto err; + /* Set r0 = (p - 1) / q */ + if (!BN_div(r0, NULL, test, q, ctx)) + goto err; + if (!generate_unverifiable_g(ctx, mont, g, tmp, p, r0, test, &hret)) + goto err; + } else if (((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0) + && !ossl_ffc_params_validate_unverifiable_g(ctx, mont, p, q, + params->g, tmp, + res)) { + goto err; + } + + if (!BN_GENCB_call(cb, GENCB_RETRY, 1)) + goto err; + + if (!verify) { + if (p != params->p) { + BN_free(params->p); + params->p = BN_dup(p); + } + if (q != params->q) { + BN_free(params->q); + params->q = BN_dup(q); + } + if (g != params->g) { + BN_free(params->g); + params->g = BN_dup(g); + } + if (params->p == NULL || params->q == NULL || params->g == NULL) + goto err; + if (!ossl_ffc_params_set_validate_params(params, seed, qsize, pcounter)) + goto err; + params->h = hret; + } +pass: + if ((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0) + ok = FFC_PARAM_RET_STATUS_UNVERIFIABLE_G; + else + ok = FFC_PARAM_RET_STATUS_SUCCESS; +err: + if (ctx != NULL) + BN_CTX_end(ctx); + BN_CTX_free(ctx); + BN_MONT_CTX_free(mont); + EVP_MD_free(md); + return ok; +} + +/* This should no longer be used in FIPS mode */ +int ossl_ffc_params_FIPS186_2_generate(OSSL_LIB_CTX *libctx, FFC_PARAMS *params, + int type, size_t L, size_t N, + int *res, BN_GENCB *cb) +{ + if (!ossl_ffc_params_FIPS186_2_gen_verify(libctx, params, + FFC_PARAM_MODE_GENERATE, + type, L, N, res, cb)) + return 0; + + ossl_ffc_params_enable_flags(params, FFC_PARAM_FLAG_VALIDATE_LEGACY, 1); + + return 1; +} + +static int generate_q_fips186_4(BN_CTX *ctx, BIGNUM *q, const EVP_MD *evpmd, + int qsize, unsigned char *seed, size_t seedlen, + int generate_seed, int *retm, int *res, + BN_GENCB *cb) +{ + int ret = 0, r; + int m = *retm; + unsigned char md[EVP_MAX_MD_SIZE]; + int mdsize = EVP_MD_get_size(evpmd); + unsigned char *pmd; + OSSL_LIB_CTX *libctx = ossl_bn_get_libctx(ctx); + + /* find q */ + for (;;) { + if (!BN_GENCB_call(cb, 0, m++)) + goto err; + + /* A.1.1.2 Step (5) : generate seed with size seed_len */ + if (generate_seed + && RAND_bytes_ex(libctx, seed, seedlen, 0) <= 0) + goto err; + /* + * A.1.1.2 Step (6) AND + * A.1.1.3 Step (7) + * U = Hash(seed) % (2^(N-1)) + */ + if (!EVP_Digest(seed, seedlen, md, NULL, evpmd, NULL)) + goto err; + /* Take least significant bits of md */ + if (mdsize > qsize) + pmd = md + mdsize - qsize; + else + pmd = md; + if (mdsize < qsize) + memset(md + mdsize, 0, qsize - mdsize); + + /* + * A.1.1.2 Step (7) AND + * A.1.1.3 Step (8) + * q = U + 2^(N-1) + (1 - U %2) (This sets top and bottom bits) + */ + pmd[0] |= 0x80; + pmd[qsize-1] |= 0x01; + if (!BN_bin2bn(pmd, qsize, q)) + goto err; + + /* + * A.1.1.2 Step (8) AND + * A.1.1.3 Step (9) + * Test if q is prime + */ + r = BN_check_prime(q, ctx, cb); + if (r > 0) { + ret = 1; + goto err; + } + /* + * A.1.1.3 Step (9) : If the provided seed didn't produce a prime q + * return an error. + */ + if (!generate_seed) { + *res |= FFC_CHECK_Q_NOT_PRIME; + goto err; + } + if (r != 0) + goto err; + /* A.1.1.2 Step (9) : if q is not prime, try another q */ + } + +err: + *retm = m; + return ret; +} + +/* + * FIPS186-4 A.2 Generation of canonical generator g. + * + * It requires the following values as input: + * 'evpmd' digest, 'p' prime, 'e' cofactor, gindex and seed. + * tmp is a passed in temporary BIGNUM. + * mont is used in a BN_mod_exp_mont() with a modulus of p. + * Returns a value in g. + */ +static int generate_canonical_g(BN_CTX *ctx, BN_MONT_CTX *mont, + const EVP_MD *evpmd, BIGNUM *g, BIGNUM *w, + const BIGNUM *p, const BIGNUM *e, + int gindex, unsigned char *seed, size_t seedlen) +{ + unsigned char md[EVP_MAX_MD_SIZE]; + EVP_MD_CTX *mctx = NULL; + int counter = 1; + int ret = 0; + int mdsize; + + mdsize = EVP_MD_get_size(evpmd); + if (mdsize <= 0) + return 0; + + mctx = EVP_MD_CTX_new(); + if (mctx == NULL) + return 0; + + /* + * A.2.3 Step (4) & (5) + * A.2.4 Step (6) & (7) + * counter = 0; counter += 1 + */ + for (counter = 1; counter <= 0xFFFF; ++counter) { + /* + * A.2.3 Step (7) & (8) & (9) + * A.2.4 Step (9) & (10) & (11) + * W = Hash(seed || "ggen" || index || counter) + * g = W^e % p + */ + static const unsigned char ggen[4] = { 0x67, 0x67, 0x65, 0x6e }; + + /* Get last 8 bits of gindex to the first byte of md */ + md[0] = (unsigned char)(gindex & 0xff); + /* Get second 8 bits of counter to the second byte of md */ + md[1] = (unsigned char)((counter >> 8) & 0xff); + /* Get last 8 bits of counter to the third byte of md */ + md[2] = (unsigned char)(counter & 0xff); + /* Compute digest: W = Hash(seed || "ggen" || index || counter) */ + if (!EVP_DigestInit_ex(mctx, evpmd, NULL) + || !EVP_DigestUpdate(mctx, seed, seedlen) + || !EVP_DigestUpdate(mctx, ggen, sizeof(ggen)) + /* Hash the first three bytes of md, corresponds to 'index || counter' */ + || !EVP_DigestUpdate(mctx, md, 3) + || !EVP_DigestFinal_ex(mctx, md, NULL) + || (BN_bin2bn(md, mdsize, w) == NULL) + || !BN_mod_exp_mont(g, w, e, p, ctx, mont)) + break; /* exit on failure */ + /* + * A.2.3 Step (10) + * A.2.4 Step (12) + * Found a value for g if (g >= 2) + */ + if (BN_cmp(g, BN_value_one()) > 0) { + ret = 1; + break; /* found g */ + } + } + + EVP_MD_CTX_free(mctx); + return ret; +} + +/* + * FIPS 186-4 FFC parameter generation (as defined in Appendix A). + * The same code is used for validation (when validate_flags != 0) + * + * The primes p & q are generated/validated using: + * A.1.1.2 Generation of probable primes p & q using approved hash. + * A.1.1.3 Validation of generated probable primes + * + * Generator 'g' has 2 types in FIPS 186-4: + * (1) A.2.1 unverifiable generation of generator g. + * A.2.2 Assurance of the validity of unverifiable generator g. + * (2) A.2.3 Verifiable Canonical Generation of the generator g. + * A.2.4 Validation for Canonical Generation of the generator g. + * + * Notes: + * (1) is only a partial validation of g, The validation of (2) requires + * the seed and index used during generation as input. + * + * params: used to pass in values for generation and validation. + * params->md: is the digest to use, If this value is NULL, then the digest is + * chosen using the value of N. + * params->flags: + * For validation one of: + * -FFC_PARAM_FLAG_VALIDATE_PQ + * -FFC_PARAM_FLAG_VALIDATE_G + * -FFC_PARAM_FLAG_VALIDATE_PQG + * For generation of p & q: + * - This is skipped if p & q are passed in. + * - If the seed is passed in then generation of p & q uses this seed (and if + * this fails an error will occur). + * - Otherwise the seed is generated, and values of p & q are generated and + * the value of seed and counter are optionally returned. + * For the generation of g (after the generation of p, q): + * - If the seed has been generated or passed in and a valid gindex is passed + * in then canonical generation of g is used otherwise unverifiable + * generation of g is chosen. + * For validation of p & q: + * - p, q, and the seed and counter used for generation must be passed in. + * For validation of g: + * - For a partial validation : p, q and g are required. + * - For a canonical validation : the gindex and seed used for generation are + * also required. + * mode: The mode - either FFC_PARAM_MODE_GENERATE or FFC_PARAM_MODE_VERIFY. + * type: The key type - FFC_PARAM_TYPE_DSA or FFC_PARAM_TYPE_DH. + * L: is the size of the prime p in bits (e.g 2048) + * N: is the size of the prime q in bits (e.g 256) + * res: A returned failure reason (One of FFC_CHECK_XXXX), + * or 0 for general failures. + * cb: A callback (can be NULL) that is called during different phases + * + * Returns: + * - FFC_PARAM_RET_STATUS_FAILED: if there was an error, or validation failed. + * - FFC_PARAM_RET_STATUS_SUCCESS if the generation or validation succeeded. + * - FFC_PARAM_RET_STATUS_UNVERIFIABLE_G if the validation of G succeeded, + * but G is unverifiable. + */ +int ossl_ffc_params_FIPS186_4_gen_verify(OSSL_LIB_CTX *libctx, + FFC_PARAMS *params, int mode, int type, + size_t L, size_t N, int *res, + BN_GENCB *cb) +{ + int ok = FFC_PARAM_RET_STATUS_FAILED; + unsigned char *seed = NULL, *seed_tmp = NULL; + int mdsize, counter = 0, pcounter = 0, r = 0; + size_t seedlen = 0; + BIGNUM *tmp, *pm1, *e, *test; + BIGNUM *g = NULL, *q = NULL, *p = NULL; + BN_MONT_CTX *mont = NULL; + int n = 0, m = 0, qsize; + int canonical_g = 0, hret = 0; + BN_CTX *ctx = NULL; + EVP_MD_CTX *mctx = NULL; + EVP_MD *md = NULL; + int verify = (mode == FFC_PARAM_MODE_VERIFY); + unsigned int flags = verify ? params->flags : 0; + const char *def_name; + + *res = 0; + + if (params->mdname != NULL) { + md = EVP_MD_fetch(libctx, params->mdname, params->mdprops); + } else { + if (N == 0) { + if (L >= L_P_2048BITS) + N = TRANS_BYTES_TO_BITS(SHA256_DIGEST_LENGTH); + else + N = TRANS_BYTES_TO_BITS(SHA_DIGEST_LENGTH); + } + + def_name = default_mdname(N); + if (def_name == NULL) { + *res = FFC_CHECK_INVALID_Q_VALUE; + goto err; + } + md = EVP_MD_fetch(libctx, def_name, params->mdprops); + } + + if (md == NULL) + goto err; + mdsize = EVP_MD_get_size(md); + if (mdsize <= 0) + goto err; + + if (N == 0) + N = TRANS_BYTES_TO_BITS((size_t)mdsize); + + qsize = TRANS_BITS_TO_BYTES(N); + + /* + * A.1.1.2 Step (1) AND + * A.1.1.3 Step (3) + * Check that the L,N pair is an acceptable pair. + */ + if (L <= N || !ffc_validate_LN(L, N, type, verify)) { + *res = FFC_CHECK_BAD_LN_PAIR; + goto err; + } + + mctx = EVP_MD_CTX_new(); + if (mctx == NULL) + goto err; + + ctx = BN_CTX_new_ex(libctx); + if (ctx == NULL) + goto err; + + BN_CTX_start(ctx); + g = BN_CTX_get(ctx); + pm1 = BN_CTX_get(ctx); + e = BN_CTX_get(ctx); + test = BN_CTX_get(ctx); + tmp = BN_CTX_get(ctx); + if (tmp == NULL) + goto err; + + seedlen = params->seedlen; + if (seedlen == 0) + seedlen = (size_t)mdsize; + /* If the seed was passed in - use this value as the seed */ + if (params->seed != NULL) + seed = params->seed; + + if (!verify) { + /* For generation: p & q must both be NULL or NON-NULL */ + if ((params->p == NULL) != (params->q == NULL)) { + *res = FFC_CHECK_INVALID_PQ; + goto err; + } + } else { + /* Validation of p,q requires seed and counter to be valid */ + if ((flags & FFC_PARAM_FLAG_VALIDATE_PQ) != 0) { + if (seed == NULL || params->pcounter < 0) { + *res = FFC_CHECK_MISSING_SEED_OR_COUNTER; + goto err; + } + } + + if ((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0) { + /* validation of g also requires g to be set */ + if (params->g == NULL) { + *res = FFC_CHECK_INVALID_G; + goto err; + } + } + } + + /* + * If p & q are passed in and + * validate_flags = 0 then skip the generation of PQ. + * validate_flags = VALIDATE_G then also skip the validation of PQ. + */ + if (params->p != NULL && ((flags & FFC_PARAM_FLAG_VALIDATE_PQ) == 0)) { + /* p and q already exists so only generate g */ + p = params->p; + q = params->q; + goto g_only; + /* otherwise to validate p & q */ + } + + /* p & q will be used for generation and validation */ + p = BN_CTX_get(ctx); + q = BN_CTX_get(ctx); + if (q == NULL) + goto err; + + /* + * A.1.1.2 Step (2) AND + * A.1.1.3 Step (6) + * Return invalid if seedlen < N + */ + if ((TRANS_BYTES_TO_BITS(seedlen)) < N) { + *res = FFC_CHECK_INVALID_SEED_SIZE; + goto err; + } + + seed_tmp = OPENSSL_malloc(seedlen); + if (seed_tmp == NULL) + goto err; + + if (seed == NULL) { + /* Validation requires the seed to be supplied */ + if (verify) { + *res = FFC_CHECK_MISSING_SEED_OR_COUNTER; + goto err; + } + /* if the seed is not supplied then alloc a seed buffer */ + seed = OPENSSL_malloc(seedlen); + if (seed == NULL) + goto err; + } + + /* A.1.1.2 Step (11): max loop count = 4L - 1 */ + counter = 4 * L - 1; + /* Validation requires the counter to be supplied */ + if (verify) { + /* A.1.1.3 Step (4) : if (counter > (4L -1)) return INVALID */ + if (params->pcounter > counter) { + *res = FFC_CHECK_INVALID_COUNTER; + goto err; + } + counter = params->pcounter; + } + + /* + * A.1.1.2 Step (3) AND + * A.1.1.3 Step (10) + * n = floor(L / hash_outlen) - 1 + */ + n = (L - 1) / (mdsize << 3); + + /* Calculate 2^(L-1): Used in step A.1.1.2 Step (11.3) */ + if (!BN_lshift(test, BN_value_one(), L - 1)) + goto err; + + for (;;) { + if (!generate_q_fips186_4(ctx, q, md, qsize, seed, seedlen, + seed != params->seed, &m, res, cb)) + goto err; + /* A.1.1.3 Step (9): Verify that q matches the expected value */ + if (verify && (BN_cmp(q, params->q) != 0)) { + *res = FFC_CHECK_Q_MISMATCH; + goto err; + } + + if (!BN_GENCB_call(cb, GENCB_NEXT, 0)) + goto err; + if (!BN_GENCB_call(cb, GENCB_RETRY, 0)) + goto err; + + memcpy(seed_tmp, seed, seedlen); + r = generate_p(ctx, md, counter, n, seed_tmp, seedlen, q, p, L, + cb, &pcounter, res); + if (r > 0) + break; /* found p */ + if (r < 0) + goto err; + /* + * A.1.1.3 Step (14): + * If we get here we failed to get a p for the given seed. If the + * seed is not random then it needs to fail (as it will always fail). + */ + if (seed == params->seed) { + *res = FFC_CHECK_P_NOT_PRIME; + goto err; + } + } + if (!BN_GENCB_call(cb, GENCB_NEXT, 1)) + goto err; + /* + * Gets here if we found p. + * A.1.1.3 Step (14): return error if i != counter OR computed_p != known_p. + */ + if (verify && (pcounter != counter || (BN_cmp(p, params->p) != 0))) + goto err; + + /* If validating p & q only then skip the g validation test */ + if ((flags & FFC_PARAM_FLAG_VALIDATE_PQG) == FFC_PARAM_FLAG_VALIDATE_PQ) + goto pass; + +g_only: + mont = BN_MONT_CTX_new(); + if (mont == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, p, ctx)) + goto err; + + if (((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0) + && !ossl_ffc_params_validate_unverifiable_g(ctx, mont, p, q, params->g, + tmp, res)) + goto err; + + /* + * A.2.1 Step (1) AND + * A.2.3 Step (3) AND + * A.2.4 Step (5) + * e = (p - 1) / q (i.e- Cofactor 'e' is given by p = q * e + 1) + */ + if (!(BN_sub(pm1, p, BN_value_one()) && BN_div(e, NULL, pm1, q, ctx))) + goto err; + + /* Canonical g requires a seed and index to be set */ + if ((seed != NULL) && (params->gindex != FFC_UNVERIFIABLE_GINDEX)) { + canonical_g = 1; + if (!generate_canonical_g(ctx, mont, md, g, tmp, p, e, + params->gindex, seed, seedlen)) { + *res = FFC_CHECK_INVALID_G; + goto err; + } + /* A.2.4 Step (13): Return valid if computed_g == g */ + if (verify && BN_cmp(g, params->g) != 0) { + *res = FFC_CHECK_G_MISMATCH; + goto err; + } + } else if (!verify) { + if (!generate_unverifiable_g(ctx, mont, g, tmp, p, e, pm1, &hret)) + goto err; + } + + if (!BN_GENCB_call(cb, GENCB_RETRY, 1)) + goto err; + + if (!verify) { + if (p != params->p) { + BN_free(params->p); + params->p = BN_dup(p); + } + if (q != params->q) { + BN_free(params->q); + params->q = BN_dup(q); + } + if (g != params->g) { + BN_free(params->g); + params->g = BN_dup(g); + } + if (params->p == NULL || params->q == NULL || params->g == NULL) + goto err; + + if (!ossl_ffc_params_set_validate_params(params, seed, seedlen, pcounter)) + goto err; + params->h = hret; + } +pass: + if ((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0 && (canonical_g == 0)) + /* Return for the case where g is partially valid */ + ok = FFC_PARAM_RET_STATUS_UNVERIFIABLE_G; + else + ok = FFC_PARAM_RET_STATUS_SUCCESS; +err: + if (seed != params->seed) + OPENSSL_free(seed); + OPENSSL_free(seed_tmp); + if (ctx != NULL) + BN_CTX_end(ctx); + BN_CTX_free(ctx); + BN_MONT_CTX_free(mont); + EVP_MD_CTX_free(mctx); + EVP_MD_free(md); + return ok; +} + +int ossl_ffc_params_FIPS186_4_generate(OSSL_LIB_CTX *libctx, FFC_PARAMS *params, + int type, size_t L, size_t N, + int *res, BN_GENCB *cb) +{ + return ossl_ffc_params_FIPS186_4_gen_verify(libctx, params, + FFC_PARAM_MODE_GENERATE, + type, L, N, res, cb); +} diff --git a/src/uadk_prov_ffc.h b/src/uadk_prov_ffc.h new file mode 100644 index 0000000..92102d3 --- /dev/null +++ b/src/uadk_prov_ffc.h @@ -0,0 +1,330 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +#ifndef UADK_PROV_FFC_H +#define UADK_PROV_FFC_H + +#include <openssl/core_names.h> +#include <openssl/dh.h> +#include <openssl/obj_mac.h> +#include <openssl/proverr.h> + +/* Default value for gindex when canonical generation of g is not used */ +#define FFC_UNVERIFIABLE_GINDEX -1 +#define FFC_PARAM_FLAG_VALIDATE_PQ 0x01 +#define FFC_PARAM_FLAG_VALIDATE_G 0x02 +#define FFC_PARAM_FLAG_VALIDATE_PQG \ + (FFC_PARAM_FLAG_VALIDATE_PQ | FFC_PARAM_FLAG_VALIDATE_G) +#define FFC_PARAM_FLAG_VALIDATE_LEGACY 0x04 + +/* The different types of FFC keys */ +#define FFC_PARAM_TYPE_DSA 0 +#define FFC_PARAM_TYPE_DH 1 + +/* + * The mode used by functions that share code for both generation and + * verification. See ossl_ffc_params_FIPS186_4_gen_verify(). + */ +#define FFC_PARAM_MODE_VERIFY 0 +#define FFC_PARAM_MODE_GENERATE 1 + +/* Return codes for generation and validation of FFC parameters */ +#define FFC_PARAM_RET_STATUS_FAILED 0 +#define FFC_PARAM_RET_STATUS_SUCCESS 1 +/* Returned if validating and g is only partially verifiable */ +#define FFC_PARAM_RET_STATUS_UNVERIFIABLE_G 2 + +/* + * NB: These values must align with the equivalently named macros in + * openssl/dh.h. We cannot use those macros here in case DH has been disabled. + */ +#define FFC_CHECK_P_NOT_PRIME 0x00001 +#define FFC_CHECK_P_NOT_SAFE_PRIME 0x00002 +#define FFC_CHECK_UNKNOWN_GENERATOR 0x00004 +#define FFC_CHECK_NOT_SUITABLE_GENERATOR 0x00008 +#define FFC_CHECK_Q_NOT_PRIME 0x00010 +#define FFC_CHECK_INVALID_Q_VALUE 0x00020 +#define FFC_CHECK_INVALID_J_VALUE 0x00040 + +#define FFC_CHECK_BAD_LN_PAIR 0x00080 +#define FFC_CHECK_INVALID_SEED_SIZE 0x00100 +#define FFC_CHECK_MISSING_SEED_OR_COUNTER 0x00200 +#define FFC_CHECK_INVALID_G 0x00400 +#define FFC_CHECK_INVALID_PQ 0x00800 +#define FFC_CHECK_INVALID_COUNTER 0x01000 +#define FFC_CHECK_P_MISMATCH 0x02000 +#define FFC_CHECK_Q_MISMATCH 0x04000 +#define FFC_CHECK_G_MISMATCH 0x08000 +#define FFC_CHECK_COUNTER_MISMATCH 0x10000 + +/* Validation Return codes */ +#define FFC_ERROR_PUBKEY_TOO_SMALL 0x01 +#define FFC_ERROR_PUBKEY_TOO_LARGE 0x02 +#define FFC_ERROR_PUBKEY_INVALID 0x04 +#define FFC_ERROR_NOT_SUITABLE_GENERATOR 0x08 +#define FFC_ERROR_PRIVKEY_TOO_SMALL 0x10 +#define FFC_ERROR_PRIVKEY_TOO_LARGE 0x20 +#define FFC_ERROR_PASSED_NULL_PARAM 0x40 + +/* How many bignums are in each "pool item"; */ +#define BN_CTX_POOL_SIZE 16 + +/* The size of prime p and prime q */ +#define L_P_512BITS 512 +#define L_P_1024BITS 1024 +#define L_P_2048BITS 2048 +#define L_P_3072BITS 3072 +#define N_Q_160BITS 160 +#define N_Q_224BITS 224 +#define N_Q_256BITS 256 + +/* Security strength of DH or DSA */ +#define SECURITY_STR_80BITS 80 +#define SECURITY_STR_112BITS 112 +#define SECURITY_STR_128BITS 128 + +#define GENCB_NEXT 2 +#define GENCB_RETRY 3 + +#define TRANS_BYTES_TO_BITS(bytes) ((bytes) << 3) +#define TRANS_BITS_TO_BYTES(bits) ((bits) >> 3) +#define PADDING_LEN(len) ((len + 63) / 64 * 64) + +#define OSSL_NELEM(x) (sizeof(x)/sizeof((x)[0])) +/* Macro to make a BIGNUM from static data */ +#define make_dh_bn(x) \ + extern const BIGNUM ossl_bignum_##x; \ + const BIGNUM ossl_bignum_##x = { \ + (BN_ULONG *) x, \ + OSSL_NELEM(x), \ + OSSL_NELEM(x), \ + 0, BN_FLG_STATIC_DATA \ + } \ + +/* + * Finite field cryptography (FFC) domain parameters are used by DH and DSA. + * Refer to FIPS186_4 Appendix A & B. + */ +typedef struct ffc_params_st { + /* Primes */ + BIGNUM *p; + BIGNUM *q; + /* Generator */ + BIGNUM *g; + /* DH X9.42 Optional Subgroup factor j >= 2 where p = j * q + 1 */ + BIGNUM *j; + + /* Required for FIPS186_4 validation of p, q and optionally canonical g */ + unsigned char *seed; + /* If this value is zero the hash size is used as the seed length */ + size_t seedlen; + /* Required for FIPS186_4 validation of p and q */ + int pcounter; + /* The identity of a named group */ + int nid; + + /* + * Required for FIPS186_4 generation & validation of canonical g. + * It uses unverifiable g if this value is -1. + */ + int gindex; + /* loop counter for unverifiable g */ + int h; + + unsigned int flags; + /* + * The digest to use for generation or validation. If this value is NULL, + * then the digest is chosen using the value of N. + */ + const char *mdname; + const char *mdprops; +#if OPENSSL_VERSION_NUMBER >= 0x30000060 + /* Default key length for known named groups according to RFC7919 */ + int keylength; +#endif +} FFC_PARAMS; + +struct bignum_st { + /* Pointer to an array of 'BN_BITS2' bit chunks. */ + BN_ULONG *d; + /* Index of last used d +1. */ + int top; + /* The next are internal book keeping for bn_expand. */ + /* Size of the d array. */ + int dmax; + /* one if the number is negative */ + int neg; + int flags; +}; + +/* A wrapper to manage the "stack frames" */ +typedef struct bignum_ctx_stack { + /* Array of indexes into the bignum stack */ + unsigned int *indexes; + /* Number of stack frames, and the size of the allocated array */ + unsigned int depth, size; +} BN_STACK; + +/* A bundle of bignums that can be linked with other bundles */ +typedef struct bignum_pool_item { + /* The bignum values */ + BIGNUM vals[BN_CTX_POOL_SIZE]; + /* Linked-list admin */ + struct bignum_pool_item *prev, *next; +} BN_POOL_ITEM; + +/* A linked-list of bignums grouped in bundles */ +typedef struct bignum_pool { + /* Linked-list admin */ + BN_POOL_ITEM *head, *current, *tail; + /* Stack depth and allocation size */ + unsigned int used, size; +} BN_POOL; + +/* The opaque BN_CTX type */ +struct bignum_ctx { + /* The bignum bundles */ + BN_POOL pool; + /* The "stack frames", if you will */ + BN_STACK stack; + /* The number of bignums currently assigned */ + unsigned int used; + /* Depth of stack overflow */ + int err_stack; + /* Block "gets" until an "end" (compatibility behaviour) */ + int too_many; + /* Flags. */ + int flags; + /* The library context */ + OSSL_LIB_CTX *libctx; +}; + +static const BN_ULONG value_2 = 2; +static const BIGNUM ossl_bignum_const_2 = { + (BN_ULONG *)&value_2, 1, 1, 0, BN_FLG_STATIC_DATA +}; + +#define declare_dh_bn(x) \ + extern const BIGNUM ossl_bignum_dh##x##_p; \ + extern const BIGNUM ossl_bignum_dh##x##_q; \ + extern const BIGNUM ossl_bignum_dh##x##_g \ + +declare_dh_bn(1024_160); +declare_dh_bn(2048_224); +declare_dh_bn(2048_256); + +extern const BIGNUM ossl_bignum_ffdhe2048_p; +extern const BIGNUM ossl_bignum_ffdhe3072_p; +extern const BIGNUM ossl_bignum_ffdhe4096_p; +extern const BIGNUM ossl_bignum_ffdhe2048_q; +extern const BIGNUM ossl_bignum_ffdhe3072_q; +extern const BIGNUM ossl_bignum_ffdhe4096_q; + +extern const BIGNUM ossl_bignum_modp_1536_p; +extern const BIGNUM ossl_bignum_modp_2048_p; +extern const BIGNUM ossl_bignum_modp_3072_p; +extern const BIGNUM ossl_bignum_modp_4096_p; + +extern const BIGNUM ossl_bignum_modp_1536_q; +extern const BIGNUM ossl_bignum_modp_2048_q; +extern const BIGNUM ossl_bignum_modp_3072_q; +extern const BIGNUM ossl_bignum_modp_4096_q; + +#define FFDHE(sz, keylength) { \ + SN_ffdhe##sz, NID_ffdhe##sz, \ + sz, \ + keylength, \ + &ossl_bignum_ffdhe##sz##_p, &ossl_bignum_ffdhe##sz##_q, \ + &ossl_bignum_const_2, \ + } + +#define MODP(sz, keylength) { \ + SN_modp_##sz, NID_modp_##sz, \ + sz, \ + keylength, \ + &ossl_bignum_modp_##sz##_p, &ossl_bignum_modp_##sz##_q, \ + &ossl_bignum_const_2 \ + } + +#define RFC5114(name, uid, sz, tag) { \ + name, uid, \ + sz, \ + 0, \ + &ossl_bignum_dh##tag##_p, &ossl_bignum_dh##tag##_q, \ + &ossl_bignum_dh##tag##_g \ + } + +struct dh_named_group_st { + const char *name; + int uid; +#ifndef OPENSSL_NO_DH + int32_t nbits; + int keylength; + const BIGNUM *p; + const BIGNUM *q; + const BIGNUM *g; +#endif +}; +typedef struct dh_named_group_st DH_NAMED_GROUP; +/* + * The private key length values are taken from RFC7919 with the values for + * MODP primes given the same lengths as the equivalent FFDHE. + * The MODP 1536 value is approximated. + */ +static const DH_NAMED_GROUP dh_named_groups[] = { + FFDHE(2048, 225), + FFDHE(3072, 275), + FFDHE(4096, 325), +#ifndef FIPS_MODULE + MODP(1536, 200), +#endif + MODP(2048, 225), + MODP(3072, 275), + MODP(4096, 325), + /* + * Additional dh named groups from RFC 5114 that have a different g. + * The uid can be any unique identifier. + */ +#ifndef FIPS_MODULE + RFC5114("dh_1024_160", 1, 1024, 1024_160), + RFC5114("dh_2048_224", 2, 2048, 2048_224), + RFC5114("dh_2048_256", 3, 2048, 2048_256), +#endif +}; + +int ossl_ffc_params_set_seed(FFC_PARAMS *params, + const unsigned char *seed, size_t seedlen); +int ossl_ffc_params_copy(FFC_PARAMS *dst, const FFC_PARAMS *src); +void ossl_ffc_params_get0_pqg(const FFC_PARAMS *d, const BIGNUM **p, + const BIGNUM **q, const BIGNUM **g); +const DH_NAMED_GROUP *ossl_ffc_uid_to_dh_named_group(int uid); +void ossl_ffc_params_set0_pqg(FFC_PARAMS *d, BIGNUM *p, BIGNUM *q, BIGNUM *g); +int ossl_ffc_named_group_set(FFC_PARAMS *ffc, const DH_NAMED_GROUP *group); +int ossl_ffc_named_group_get_uid(const DH_NAMED_GROUP *group); +void ossl_ffc_params_set_gindex(FFC_PARAMS *params, int index); +void ossl_ffc_params_set_pcounter(FFC_PARAMS *params, int index); +void ossl_ffc_params_set_h(FFC_PARAMS *params, int index); +int ossl_ffc_set_digest(FFC_PARAMS *params, const char *alg, const char *props); +void ossl_ffc_params_enable_flags(FFC_PARAMS *params, unsigned int flags, + int enable); +int ossl_ffc_params_cmp(const FFC_PARAMS *a, const FFC_PARAMS *b, int ignore_q); +void ossl_ffc_params_init(FFC_PARAMS *params); +void ossl_ffc_params_cleanup(FFC_PARAMS *params); +int ossl_ffc_params_FIPS186_2_generate(OSSL_LIB_CTX *libctx, FFC_PARAMS *params, + int type, size_t L, size_t N, + int *res, BN_GENCB *cb); +int ossl_ffc_params_FIPS186_2_gen_verify(OSSL_LIB_CTX *libctx, + FFC_PARAMS *params, int mode, int type, + size_t L, size_t N, int *res, + BN_GENCB *cb); +int ossl_ffc_params_FIPS186_4_generate(OSSL_LIB_CTX *libctx, FFC_PARAMS *params, + int type, size_t L, size_t N, + int *res, BN_GENCB *cb); + +#endif
Based on the original implementation, a unified data structure is used. And FFC-related extended functions are added.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_prov.h | 4 +- src/uadk_prov_dh.c | 2611 ++++++++++++++++++++++-------------------- src/uadk_prov_init.c | 1 + src/uadk_prov_pkey.h | 106 ++ 4 files changed, 1509 insertions(+), 1213 deletions(-)
diff --git a/src/uadk_prov.h b/src/uadk_prov.h index 1b8aab9..1b4816e 100644 --- a/src/uadk_prov.h +++ b/src/uadk_prov.h @@ -146,8 +146,8 @@ extern const OSSL_DISPATCH uadk_rsa_signature_functions[FUNC_MAX_NUM]; extern const OSSL_DISPATCH uadk_rsa_keymgmt_functions[FUNC_MAX_NUM]; extern const OSSL_DISPATCH uadk_rsa_asym_cipher_functions[FUNC_MAX_NUM];
-extern const OSSL_DISPATCH uadk_dh_keymgmt_functions[]; -extern const OSSL_DISPATCH uadk_dh_keyexch_functions[]; +extern const OSSL_DISPATCH uadk_dh_keymgmt_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_dh_keyexch_functions[FUNC_MAX_NUM];
extern const OSSL_DISPATCH uadk_sm2_keymgmt_functions[FUNC_MAX_NUM]; extern const OSSL_DISPATCH uadk_sm2_signature_functions[FUNC_MAX_NUM]; diff --git a/src/uadk_prov_dh.c b/src/uadk_prov_dh.c index 5d35a6a..b7184c0 100644 --- a/src/uadk_prov_dh.c +++ b/src/uadk_prov_dh.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 /* * Copyright 2023-2024 Huawei Technologies Co.,Ltd. All rights reserved. * Copyright 2023-2024 Linaro ltd. @@ -16,97 +17,49 @@ * */ #include <openssl/core_names.h> -#include <openssl/proverr.h> #include <openssl/dh.h> +#include <openssl/kdf.h> +#include <openssl/proverr.h> #include <uadk/wd_dh.h> #include <uadk/wd_sched.h> #include "uadk.h" #include "uadk_async.h" #include "uadk_prov.h" +#include "uadk_prov_ffc.h" +#include "uadk_prov_pkey.h" + +#define DH768BITS 768 +#define DH1024BITS 1024 +#define DH1536BITS 1536 +#define DH2048BITS 2048 +#define DH3072BITS 3072 +#define DH4096BITS 4096 +#define UADK_DH_MAX_MODULE_BIT 4096 +#define DH_GENERATOR_2 2 +#define CHAR_BIT_SIZE 3 +#define DH_PARAMS_CNT 3 +#define CTX_MODE_NUM 2 +#define UN_SET 0 +#define IS_SET 1 +#define CTX_ASYNC 1 +#define CTX_SYNC 0 +#define CTX_NUM 2 +#define UADK_DO_SOFT (-0xE0) +#define UADK_P_INIT_SUCCESS 0 +#define ENV_ENABLED 1 +#define KEY_GEN_BY_PROV 1 +#define KEY_GEN_BY_USR 0 +#define RAND_MAX_CNT 1000 +#define LEN_ZERO 0 +#define DH_MAX_PARAM_LEN 80 +#define IGNORE_Q 1 +#define USE_PAD 1 +#define KDF_PARAM_NUM 5 + +UADK_PKEY_KEYMGMT_DESCR(dh, DH); +UADK_PKEY_KEYEXCH_DESCR(dh, DH);
-#define DH768BITS 768 -#define DH1024BITS 1024 -#define DH1536BITS 1536 -#define DH2048BITS 2048 -#define DH3072BITS 3072 -#define DH4096BITS 4096 -#define UADK_DH_MAX_MODULE_BIT 4096 -#define DH_GENERATOR_2 2 -#define DH_GENERATOR_5 5 -#define CHAR_BIT_SIZE 3 -#define DH_PARAMS_CNT 3 -#define CTX_MODE_NUM 2 -#define UN_SET 0 -#define IS_SET 1 -#define CTX_ASYNC 1 -#define CTX_SYNC 0 -#define CTX_NUM 2 -#define UADK_DO_SOFT (-0xE0) -#define UADK_E_SUCCESS 1 -#define UADK_E_FAIL 0 -#define UADK_E_POLL_SUCCESS 0 -#define UADK_E_POLL_FAIL (-1) -#define UADK_E_INIT_SUCCESS 0 -#define ENV_ENABLED 1 -#define KEY_GEN_BY_ENGINE 1 - -struct evp_keyexch_st { - int name_id; - char *type_name; - const char *description; - OSSL_PROVIDER *prov; - CRYPTO_REF_COUNT refcnt; -# if OPENSSL_VERSION_NUMBER < 0x30200000 - CRYPTO_RWLOCK *lock; -# endif - OSSL_FUNC_keyexch_newctx_fn *newctx; - OSSL_FUNC_keyexch_init_fn *init; - OSSL_FUNC_keyexch_set_peer_fn *set_peer; - OSSL_FUNC_keyexch_derive_fn *derive; - OSSL_FUNC_keyexch_freectx_fn *freectx; - OSSL_FUNC_keyexch_dupctx_fn *dupctx; - OSSL_FUNC_keyexch_set_ctx_params_fn *set_ctx_params; - OSSL_FUNC_keyexch_settable_ctx_params_fn *settable_ctx_params; - OSSL_FUNC_keyexch_get_ctx_params_fn *get_ctx_params; - OSSL_FUNC_keyexch_gettable_ctx_params_fn *gettable_ctx_params; -} /* EVP_KEYEXCH */; - -typedef struct ffc_params_st { - /* Primes */ - BIGNUM *p; - BIGNUM *q; - /* Generator */ - BIGNUM *g; - /* DH X9.42 Optional Subgroup factor j >= 2 where p = j * q + 1 */ - BIGNUM *j; - - /* Required for FIPS186_4 validation of p, q and optionally canonical g */ - unsigned char *seed; - /* If this value is zero the hash size is used as the seed length */ - size_t seedlen; - /* Required for FIPS186_4 validation of p and q */ - int pcounter; - int nid; /* The identity of a named group */ - - /* - * Required for FIPS186_4 generation & validation of canonical g. - * It uses unverifiable g if this value is -1. - */ - int gindex; - int h; /* loop counter for unverifiable g */ - - unsigned int flags; - /* - * The digest to use for generation or validation. If this value is NULL, - * then the digest is chosen using the value of N. - */ - const char *mdname; - const char *mdprops; -#if OPENSSL_VERSION_NUMBER >= 0x30000060 - /* Default key length for known named groups according to RFC7919 */ - int keylength; -#endif -} FFC_PARAMS; +static pthread_mutex_t dh_mutex = PTHREAD_MUTEX_INITIALIZER;
struct dh_st { /* @@ -122,17 +75,18 @@ struct dh_st { BIGNUM *priv_key; /* x */ int flags; BN_MONT_CTX *method_mont_p; - CRYPTO_REF_COUNT references; + int references; #ifndef FIPS_MODULE CRYPTO_EX_DATA ex_data; ENGINE *engine; #endif OSSL_LIB_CTX * libctx; const DH_METHOD *meth; - CRYPTO_RWLOCK *lock; + void *lock;
/* Provider data */ - size_t dirty_cnt; /* If any key material changes, increment this */ + /* If any key material changes, increment this */ + size_t dirty_cnt; }; /* DH */
struct dh_method { @@ -154,27 +108,22 @@ struct dh_method { BN_GENCB *cb); };
-#define FFC_UNVERIFIABLE_GINDEX -1 -#define FFC_PARAM_FLAG_VALIDATE_PQ 0x01 -#define FFC_PARAM_FLAG_VALIDATE_G 0x02 -#define FFC_PARAM_FLAG_VALIDATE_PQG \ - (FFC_PARAM_FLAG_VALIDATE_PQ | FFC_PARAM_FLAG_VALIDATE_G) - struct uadk_dh_sess { handle_t sess; struct wd_dh_sess_setup setup; struct wd_dh_req req; DH *alg; __u16 key_size; - /* key_flag: 0 - key is defined by user, 1 - key is generated by engine */ + /* + * key_flag: 0 - key is defined by user + * 1 - key is generated by provider + */ int key_flag; };
struct dh_res { int pid; -} g_dh_res; - -static pthread_mutex_t dh_mutex = PTHREAD_MUTEX_INITIALIZER; +} g_dh_prov;
/* * This type is only really used to handle some legacy related functionality. @@ -191,33 +140,8 @@ enum kdf_type { PROV_DH_KDF_X9_42_ASN1 };
-/* - * What's passed as an actual key is defined by the KEYMGMT interface. - * We happen to know that our KEYMGMT simply passes DH structures, so - * we use that here too. - */ - typedef struct { OSSL_LIB_CTX *libctx; - DH *dh; - DH *dhpeer; - unsigned int pad : 1; - - /* DH KDF */ - /* KDF (if any) to use for DH */ - enum kdf_type kdf_type; - /* Message digest to use for key derivation */ - EVP_MD *kdf_md; - /* User key material */ - unsigned char *kdf_ukm; - size_t kdf_ukmlen; - /* KDF output length */ - size_t kdf_outlen; - char *kdf_cekalg; -} UADK_PROV_DH_CTX; - -struct dh_gen_ctx { - OSSL_LIB_CTX *libctx;
FFC_PARAMS *ffc_params; int selection; @@ -240,212 +164,247 @@ struct dh_gen_ctx { OSSL_CALLBACK *cb; void *cbarg; int dh_type; -}; +} PROV_DH_KEYMGMT_CTX;
+/* + * What's passed as an actual key is defined by the KEYMGMT interface. + * We happen to know that our KEYMGMT simply passes DH structures, so + * we use that here too. + */ typedef struct { - int id; /* libcrypto internal */ - int name_id; - char *type_name; - const char *description; - OSSL_PROVIDER *prov; - - CRYPTO_REF_COUNT refcnt; -# if OPENSSL_VERSION_NUMBER < 0x30200000 - CRYPTO_RWLOCK *lock; -# endif - - /* Constructor(s), destructor, information */ - OSSL_FUNC_keymgmt_new_fn *new; - OSSL_FUNC_keymgmt_free_fn *free; - OSSL_FUNC_keymgmt_get_params_fn *get_params; - OSSL_FUNC_keymgmt_gettable_params_fn *gettable_params; - OSSL_FUNC_keymgmt_set_params_fn *set_params; - OSSL_FUNC_keymgmt_settable_params_fn *settable_params; - - /* Generation, a complex constructor */ - OSSL_FUNC_keymgmt_gen_init_fn *gen_init; - OSSL_FUNC_keymgmt_gen_set_template_fn *gen_set_template; - OSSL_FUNC_keymgmt_gen_set_params_fn *gen_set_params; - OSSL_FUNC_keymgmt_gen_settable_params_fn *gen_settable_params; - OSSL_FUNC_keymgmt_gen_fn *gen; - OSSL_FUNC_keymgmt_gen_cleanup_fn *gen_cleanup; - OSSL_FUNC_keymgmt_load_fn *load; - - /* Key object checking */ - OSSL_FUNC_keymgmt_query_operation_name_fn *query_operation_name; - OSSL_FUNC_keymgmt_has_fn *has; - OSSL_FUNC_keymgmt_validate_fn *validate; - OSSL_FUNC_keymgmt_match_fn *match; - - /* Import and export routines */ - OSSL_FUNC_keymgmt_import_fn *import; - OSSL_FUNC_keymgmt_import_types_fn *import_types; -# if OPENSSL_VERSION_NUMBER >= 0x30200000 - OSSL_FUNC_keymgmt_import_types_ex_fn *import_types_ex; -# endif - OSSL_FUNC_keymgmt_export_fn *export; - OSSL_FUNC_keymgmt_export_types_fn *export_types; -# if OPENSSL_VERSION_NUMBER >= 0x30200000 - OSSL_FUNC_keymgmt_export_types_ex_fn *export_types_ex; -# endif - OSSL_FUNC_keymgmt_dup_fn *dup; - -} UADK_DH_KEYMGMT; - -static inline int CRYPTO_UP_REF(int *val, int *ret, ossl_unused void *lock) -{ - *ret = __atomic_fetch_add(val, 1, __ATOMIC_RELAXED) + 1; - return 1; -} - -static inline int CRYPTO_DOWN_REF(int *val, int *ret, - ossl_unused void *lock) -{ - *ret = __atomic_fetch_sub(val, 1, __ATOMIC_RELAXED) - 1; - if (*ret == 0) - __atomic_thread_fence(__ATOMIC_ACQUIRE); - return 1; -} - -static FFC_PARAMS *uadk_dh_get0_params(DH *dh) + OSSL_LIB_CTX *libctx; + DH *dh; + DH *dhpeer; + unsigned int pad : 1; + + /* DH KDF */ + /* KDF (if any) to use for DH */ + enum kdf_type kdf_type; + /* Message digest to use for key derivation */ + EVP_MD *kdf_md; + /* User key material */ + unsigned char *kdf_ukm; + size_t kdf_ukmlen; + /* KDF output length */ + size_t kdf_outlen; + char *kdf_cekalg; +} PROV_DH_KEYEXCH_CTX; + +static void *uadk_keymgmt_dh_new(void *provctx) { - return &dh->params; + if (get_default_keymgmt().new_fun == NULL) + return NULL; + + return get_default_keymgmt().new_fun(provctx); }
-static int uadk_DH_size(const DH *dh) +static void uadk_keymgmt_dh_free(void *keydata) { - if (dh->params.p != NULL) - return BN_num_bytes(dh->params.p); - return -1; + if (get_default_keymgmt().free == NULL) + return; + + get_default_keymgmt().free(keydata); }
-static void uadk_DH_get0_key(const DH *dh, const BIGNUM **pub_key, - const BIGNUM **priv_key) +static int uadk_keymgmt_dh_has(const void *keydata, int selection) { - if (pub_key != NULL) - *pub_key = dh->pub_key; - if (priv_key != NULL) - *priv_key = dh->priv_key; + if (get_default_keymgmt().has == NULL) + return UADK_P_FAIL; + + return get_default_keymgmt().has(keydata, selection); }
-static int uadk_DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) +static int uadk_keymgmt_dh_match(const void *keydata1, const void *keydata2, int selection) { - if (pub_key != NULL) { - BN_clear_free(dh->pub_key); - dh->pub_key = pub_key; - } + if (get_default_keymgmt().match == NULL) + return UADK_P_FAIL;
- if (priv_key != NULL) { - BN_clear_free(dh->priv_key); - dh->priv_key = priv_key; - } + return get_default_keymgmt().match(keydata1, keydata2, selection); +}
- dh->dirty_cnt++; - return 1; +static int uadk_keymgmt_dh_import(void *keydata, int selection, const OSSL_PARAM params[]) +{ + if (get_default_keymgmt().import == NULL) + return UADK_P_FAIL; + + return get_default_keymgmt().import(keydata, selection, params); }
-static FFC_PARAMS *uadk_ossl_dh_get0_params(DH *dh) +static int uadk_keymgmt_dh_export(void *keydata, int selection, OSSL_CALLBACK *cb, void *cb_params) { - return &dh->params; + if (get_default_keymgmt().export_fun == NULL) + return UADK_P_FAIL; + + return get_default_keymgmt().export_fun(keydata, selection, cb, cb_params); }
-static const BIGNUM *uadk_DH_get0_p(const DH *dh) +static const OSSL_PARAM *uadk_keymgmt_dh_import_types(int selection) { - return dh->params.p; + if (get_default_keymgmt().import_types == NULL) + return NULL; + + return get_default_keymgmt().import_types(selection); }
-static int ossl_ffc_params_set_seed(FFC_PARAMS *params, - const unsigned char *seed, size_t seedlen) +static const OSSL_PARAM *uadk_keymgmt_dh_export_types(int selection) { - if (params == NULL) - return 0; + if (get_default_keymgmt().export_types == NULL) + return NULL;
- if (params->seed != NULL) { - if (params->seed == seed) - return 1; - OPENSSL_free(params->seed); - } + return get_default_keymgmt().export_types(selection); +}
- if (seed != NULL && seedlen > 0) { - params->seed = OPENSSL_memdup(seed, seedlen); - if (params->seed == NULL) - return 0; - params->seedlen = seedlen; - } else { - params->seed = NULL; - params->seedlen = 0; - } - return 1; +static ossl_inline int uadk_keymgmt_dh_get_params(void *key, OSSL_PARAM params[]) +{ + if (get_default_keymgmt().get_params == NULL) + return UADK_P_FAIL; + + return get_default_keymgmt().get_params(key, params); }
-static int ffc_bn_cpy(BIGNUM **dst, const BIGNUM *src) +static const OSSL_PARAM *uadk_keymgmt_dh_gettable_params(void *provctx) { - BIGNUM *a; + if (get_default_keymgmt().gettable_params == NULL) + return NULL;
- /* - * If source is read only just copy the pointer, so - * we don't have to reallocate it. - */ - if (src == NULL) - a = NULL; - else if (BN_get_flags(src, BN_FLG_STATIC_DATA) - && !BN_get_flags(src, BN_FLG_MALLOCED)) - a = (BIGNUM *)src; - else { - a = BN_dup(src); - if (a == NULL) - return 0; - } + return get_default_keymgmt().gettable_params(provctx); +} + +static const OSSL_PARAM *uadk_keymgmt_dh_settable_params(void *provctx) +{ + if (get_default_keymgmt().settable_params == NULL) + return NULL;
- BN_clear_free(*dst); - *dst = a; - return 1; + return get_default_keymgmt().settable_params(provctx); }
-static int ossl_ffc_params_copy(FFC_PARAMS *dst, const FFC_PARAMS *src) +static int uadk_keymgmt_dh_set_params(void *key, const OSSL_PARAM params[]) { - if (!ffc_bn_cpy(&dst->p, src->p) - || !ffc_bn_cpy(&dst->g, src->g) - || !ffc_bn_cpy(&dst->q, src->q) - || !ffc_bn_cpy(&dst->j, src->j)) - return 0; + if (get_default_keymgmt().set_params == NULL) + return UADK_P_FAIL;
- OPENSSL_free(dst->seed); - dst->seedlen = src->seedlen; - if (src->seed != NULL) { - dst->seed = OPENSSL_memdup(src->seed, src->seedlen); - if (dst->seed == NULL) - return 0; - } else { - dst->seed = NULL; + return get_default_keymgmt().set_params(key, params); +} + +static int uadk_keymgmt_dh_validate(const void *keydata, int selection, int checktype) +{ + if (get_default_keymgmt().validate == NULL) + return UADK_P_FAIL; + + return get_default_keymgmt().validate(keydata, selection, checktype); +} + +static void *uadk_keymgmt_dh_gen_init(void *provctx, int selection, + const OSSL_PARAM params[]) +{ + if (get_default_keymgmt().gen_init == NULL) + return NULL; + + return get_default_keymgmt().gen_init(provctx, selection, params); +} + +static int uadk_keymgmt_dh_gen_set_template(void *genctx, void *templ) +{ + if (get_default_keymgmt().gen_set_template == NULL) + return UADK_P_FAIL; + + return get_default_keymgmt().gen_set_template(genctx, templ); +} + +static const OSSL_PARAM *uadk_keymgmt_dh_gen_settable_params(ossl_unused void *genctx, + ossl_unused void *provctx) +{ + if (get_default_keymgmt().gen_settable_params == NULL) + return NULL; + + return get_default_keymgmt().gen_settable_params(genctx, provctx); +} + +static int uadk_keymgmt_dh_gen_set_params(void *genctx, + const OSSL_PARAM params[]) +{ + if (get_default_keymgmt().gen_set_params == NULL) + return UADK_P_FAIL; + + return get_default_keymgmt().gen_set_params(genctx, params); +} + +static void uadk_keymgmt_dh_gen_cleanup(void *genctx) +{ + if (get_default_keymgmt().gen_cleanup == NULL) + return; + + get_default_keymgmt().gen_cleanup(genctx); +} + +static void *uadk_keymgmt_dh_load(const void *reference, size_t reference_sz) +{ + if (get_default_keymgmt().load == NULL) + return NULL; + + return get_default_keymgmt().load(reference, reference_sz); +} + +static void *uadk_keymgmt_dh_dup(const void *keydata_from, int selection) +{ + if (get_default_keymgmt().dup == NULL) + return NULL; + + return get_default_keymgmt().dup(keydata_from, selection); +} + +static int uadk_DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) +{ + if (dh == NULL) { + fprintf(stderr, "invalid: dh is NULL\n"); + return UADK_P_FAIL; + } + + if (pub_key != NULL) { + BN_clear_free(dh->pub_key); + dh->pub_key = pub_key; } - dst->nid = src->nid; - dst->pcounter = src->pcounter; - dst->h = src->h; - dst->gindex = src->gindex; - dst->flags = src->flags; - return 1; + + if (priv_key != NULL) { + BN_clear_free(dh->priv_key); + dh->priv_key = priv_key; + } + + dh->dirty_cnt++; + + return UADK_P_SUCCESS; +} + +static FFC_PARAMS *ossl_dh_get0_params(DH *dh) +{ + if (dh == NULL) + return NULL; + + return &dh->params; +} + +static const BIGNUM *uadk_DH_get0_p(const DH *dh) +{ + if (dh == NULL) + return NULL; + + return dh->params.p; }
static const BIGNUM *uadk_DH_get0_q(const DH *dh) { + if (dh == NULL) + return NULL; + return dh->params.q; }
static long uadk_DH_get_length(const DH *dh) { - return dh->length; -} + if (dh == NULL) + return LEN_ZERO;
-static void ossl_ffc_params_get0_pqg(const FFC_PARAMS *d, const BIGNUM **p, - const BIGNUM **q, const BIGNUM **g) -{ - if (p != NULL) - *p = d->p; - if (q != NULL) - *q = d->q; - if (g != NULL) - *g = d->g; + return dh->length; }
static void uadk_DH_get0_pqg(const DH *dh, const BIGNUM **p, @@ -456,19 +415,31 @@ static void uadk_DH_get0_pqg(const DH *dh, const BIGNUM **p,
static const BIGNUM *uadk_DH_get0_priv_key(const DH *dh) { + if (dh == NULL) + return NULL; + return dh->priv_key; }
static const BIGNUM *uadk_DH_get0_pub_key(const DH *dh) { + if (dh == NULL) + return NULL; + return dh->pub_key; }
static int uadk_DH_bits(const DH *dh) { + int bits = 0; + + if (dh == NULL) + return bits; + if (dh->params.p != NULL) - return BN_num_bits(dh->params.p); - return -1; + bits = BN_num_bits(dh->params.p); + + return bits; }
static void uadk_DH_clear_flags(DH *dh, int flags) @@ -481,85 +452,77 @@ static void uadk_DH_set_flags(DH *dh, int flags) dh->flags |= flags; }
-static int uadk_ffc_params_cmp(const FFC_PARAMS *a, const FFC_PARAMS *b, int ignore_q) -{ - return BN_cmp(a->p, b->p) == 0 && BN_cmp(a->g, b->g) == 0 && - (ignore_q || BN_cmp(a->q, b->q) == 0); /* Note: q may be NULL */ -} - -static int uadk_DH_up_ref(DH *r) -{ - int i; - - if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) - return 0; - - if (i < 2) { - fprintf(stderr, "refcount error.\n"); - return 0; - } - return ((i > 1) ? 1 : 0); -} - -static EVP_KEYEXCH get_default_keyexch(void) -{ - static EVP_KEYEXCH s_keyexch; - static int initilazed; - - if (!initilazed) { - EVP_KEYEXCH *keyexch = - (EVP_KEYEXCH *)EVP_KEYEXCH_fetch(NULL, "DH", "provider=default"); - if (keyexch) { - s_keyexch = *keyexch; - EVP_KEYEXCH_free((EVP_KEYEXCH *)keyexch); - initilazed = 1; - } else { - fprintf(stderr, "EVP_KEYEXCH_fetch from default provider failed"); - } - } - return s_keyexch; -} - -static int dh_generate_new_priv_key(const DH *dh, BIGNUM *new_priv_key) +static int dh_gen_rand_prikey(const DH *dh, BIGNUM *new_prikey) { const BIGNUM *q = uadk_DH_get0_q(dh); - int bits; + int bits, cnt;
if (q) { + cnt = 0; do { - if (!BN_priv_rand_range(new_priv_key, q)) - return UADK_E_FAIL; - } while (BN_is_zero(new_priv_key) || BN_is_one(new_priv_key)); + if (!BN_priv_rand_range(new_prikey, q)) { + fprintf(stderr, "failed to BN_priv_rand_range\n"); + return UADK_P_FAIL; + } + + cnt++; + if (cnt > RAND_MAX_CNT) { + fprintf(stderr, "failed to get appropriate prikey, timeout\n"); + return UADK_P_FAIL; + } + } while (BN_is_zero(new_prikey) || BN_is_one(new_prikey)); } else { bits = uadk_DH_get_length(dh) ? uadk_DH_get_length(dh) : BN_num_bits(uadk_DH_get0_p(dh)) - 1; - if (!BN_priv_rand(new_priv_key, bits, BN_RAND_TOP_ONE, - BN_RAND_BOTTOM_ANY)) - return UADK_E_FAIL; + if (!BN_priv_rand(new_prikey, bits, BN_RAND_TOP_ONE, + BN_RAND_BOTTOM_ANY)) { + fprintf(stderr, "failed to BN_priv_rand\n"); + return UADK_P_FAIL; + } }
- return UADK_E_SUCCESS; + return UADK_P_SUCCESS; }
-static int dh_try_get_priv_key(struct uadk_dh_sess *dh_sess, const DH *dh, BIGNUM **priv_key) +static int uadk_prov_dh_prepare_prikey(struct uadk_dh_sess *dh_sess, const DH *dh, BIGNUM **prikey) { - *priv_key = (BIGNUM *)uadk_DH_get0_priv_key(dh); - if (!(*priv_key)) { - *priv_key = BN_secure_new(); - if (!(*priv_key)) - return UADK_E_FAIL; + *prikey = (BIGNUM *)uadk_DH_get0_priv_key(dh);
- if (!dh_generate_new_priv_key(dh, *priv_key)) - goto err; + if (*prikey == NULL) { + *prikey = BN_secure_new(); + if (*prikey == NULL) { + fprintf(stderr, "failed to do BN_secure_new\n"); + return UADK_P_FAIL; + }
- dh_sess->key_flag = KEY_GEN_BY_ENGINE; + if (dh_gen_rand_prikey(dh, *prikey) == UADK_P_FAIL) { + fprintf(stderr, "failed to generate new private key\n"); + goto free_prikey; + } + + dh_sess->key_flag = KEY_GEN_BY_PROV; + } else { + dh_sess->key_flag = KEY_GEN_BY_USR; }
- return UADK_E_SUCCESS; + return UADK_P_SUCCESS;
-err: - BN_free(*priv_key); - return UADK_E_FAIL; +free_prikey: + /* Free the prikey generated by uadk provider */ + BN_free(*prikey); + *prikey = NULL; + + return UADK_P_FAIL; +} + +static void uadk_prov_dh_free_prikey(struct uadk_dh_sess *dh_sess, BIGNUM *prikey) +{ + if (dh_sess == NULL) + return; + + /* User generated key will be freed by user, not uadk provider */ + if (prikey && dh_sess->key_flag == KEY_GEN_BY_PROV) + BN_free(prikey); }
static void uadk_prov_dh_cb(void *req_t) @@ -569,19 +532,19 @@ static void uadk_prov_dh_cb(void *req_t) struct wd_dh_req *req_origin; struct async_op *op;
- if (!req_new) + if (req_new == NULL) return;
cb_param = req_new->cb_param; - if (!cb_param) + if (cb_param == NULL) return;
req_origin = cb_param->priv; - if (!req_origin) + if (req_origin == NULL) return;
req_origin->status = req_new->status; - if (!req_origin->status) + if (req_origin->status == 0) req_origin->pri_bytes = req_new->pri_bytes;
op = cb_param->op; @@ -592,7 +555,7 @@ static void uadk_prov_dh_cb(void *req_t) } }
-static int uadk_dh_env_poll(void *ctx) +static int uadk_prov_dh_poll(void *ctx) { __u64 rx_cnt = 0; __u32 recv = 0; @@ -605,106 +568,88 @@ static int uadk_dh_env_poll(void *ctx) if (ret < 0 || recv == expt) return ret; rx_cnt++; - } while (rx_cnt < ENGINE_RECV_MAX_CNT); + } while (rx_cnt < PROV_ENV_RECV_MAX_CNT);
fprintf(stderr, "failed to poll msg: timeout!\n");
return -ETIMEDOUT; }
+static void uadk_prov_dh_mutex_infork(void) +{ + /* Release the replication lock of the child process */ + pthread_mutex_unlock(&dh_mutex); +} + static int uadk_prov_dh_init(void) { int ret;
+ pthread_atfork(NULL, NULL, uadk_prov_dh_mutex_infork); pthread_mutex_lock(&dh_mutex); - if (g_dh_res.pid != getpid()) { - ret = wd_dh_init2("dh", 0, 0); - if (unlikely(ret)) + if (g_dh_prov.pid != getpid()) { + ret = wd_dh_init2("dh", SCHED_POLICY_RR, TASK_HW); + if (unlikely(ret)) { + pthread_mutex_unlock(&dh_mutex); return ret; - g_dh_res.pid = getpid(); - async_register_poll_fn(ASYNC_TASK_DH, uadk_dh_env_poll); + } + g_dh_prov.pid = getpid(); + async_register_poll_fn(ASYNC_TASK_DH, uadk_prov_dh_poll); } pthread_mutex_unlock(&dh_mutex);
- return UADK_E_INIT_SUCCESS; + return UADK_P_INIT_SUCCESS; }
-static struct uadk_dh_sess *dh_new_eng_session(DH *dh_alg) +/* Uninit only when the process exits, not uninit when thread exits */ +void uadk_prov_dh_uninit(void) { - struct uadk_dh_sess *dh_sess; - - dh_sess = OPENSSL_malloc(sizeof(struct uadk_dh_sess)); - if (!dh_sess) - return NULL; - - memset(dh_sess, 0, sizeof(struct uadk_dh_sess)); - - dh_sess->alg = dh_alg; - - return dh_sess; + pthread_mutex_lock(&dh_mutex); + if (g_dh_prov.pid == getpid()) { + wd_dh_uninit2(); + g_dh_prov.pid = 0; + } + pthread_mutex_unlock(&dh_mutex); }
-static int dh_init_eng_session(struct uadk_dh_sess *dh_sess, - __u16 bits, bool is_g2) +static struct uadk_dh_sess *uadk_prov_dh_new_session(DH *dh, __u16 bits, bool is_g2) { + struct uadk_dh_sess *dh_sess = OPENSSL_zalloc(sizeof(struct uadk_dh_sess)); __u16 key_size = bits >> CHAR_BIT_SIZE; struct sched_params params = {0};
- if (dh_sess->sess && dh_sess->req.x_p) { - memset(dh_sess->req.x_p, 0, dh_sess->req.pbytes + - dh_sess->req.xbytes); - return UADK_E_SUCCESS; + if (dh_sess == NULL) { + fprintf(stderr, "failed to alloc dh session\n"); + return NULL; }
- if (!dh_sess->sess) { - dh_sess->key_size = key_size; - dh_sess->setup.key_bits = bits; - dh_sess->setup.is_g2 = is_g2; - /* Use the default numa parameters */ - params.numa_id = -1; - dh_sess->setup.sched_param = ¶ms; - dh_sess->sess = wd_dh_alloc_sess(&dh_sess->setup); - if (!dh_sess->sess) - return UADK_E_FAIL; + dh_sess->alg = dh; + dh_sess->key_size = key_size; + dh_sess->setup.key_bits = bits; + dh_sess->setup.is_g2 = is_g2; + /* Use the default numa parameters */ + params.numa_id = -1; + dh_sess->setup.sched_param = ¶ms; + dh_sess->sess = wd_dh_alloc_sess(&dh_sess->setup); + if (dh_sess->sess == (handle_t)0) { + fprintf(stderr, "failed to init dh sess\n"); + OPENSSL_free(dh_sess); + return NULL; }
- return UADK_E_SUCCESS; + return dh_sess; }
-static void dh_free_eng_session(struct uadk_dh_sess *dh_sess) +static void uadk_prov_dh_free_session(struct uadk_dh_sess *dh_sess) { - if (!dh_sess) + if (dh_sess == NULL) return;
if (dh_sess->sess) wd_dh_free_sess(dh_sess->sess);
- if (dh_sess->req.x_p) - OPENSSL_free(dh_sess->req.x_p); - - if (dh_sess->req.pv) - OPENSSL_free(dh_sess->req.pv); - - OPENSSL_free(dh_sess); -} - -static struct uadk_dh_sess *dh_get_eng_session(DH *dh, __u16 bits, - bool is_g2) -{ - struct uadk_dh_sess *dh_sess = dh_new_eng_session(dh); - int ret; - - if (!dh_sess) - return NULL; - - ret = dh_init_eng_session(dh_sess, bits, is_g2); - if (!ret) { - dh_free_eng_session(dh_sess); - return NULL; - } - - return dh_sess; -} + OPENSSL_free(dh_sess); +}
static int check_dh_bit_useful(const __u16 bits) { @@ -714,7 +659,7 @@ static int check_dh_bit_useful(const __u16 bits) * OPENSSL_DH_MAX_MODULUS_BITS, 10000 bits. * OpenSSL speed tool supports 2048/3072/4096/6144/8192 bits. * UADK supports 768/1024/1536/2048/3072/4096 bits. - * UADK-engine will be consistent with UADK. + * UADK-provider will be consistent with UADK. */ switch (bits) { case DH768BITS: @@ -723,17 +668,16 @@ static int check_dh_bit_useful(const __u16 bits) case DH2048BITS: case DH3072BITS: case DH4096BITS: - return UADK_E_SUCCESS; + return UADK_P_SUCCESS; default: break; }
- return UADK_E_FAIL; + return UADK_P_FAIL; }
-static int dh_prepare_data(const BIGNUM *g, DH *dh, - struct uadk_dh_sess **dh_sess, - BIGNUM **priv_key) +static int uadk_prov_dh_prepare_data(const BIGNUM *g, DH *dh, struct uadk_dh_sess **dh_sess, + BIGNUM **prikey) { bool is_g2 = BN_is_word(g, DH_GENERATOR_2); __u16 bits; @@ -744,178 +688,149 @@ static int dh_prepare_data(const BIGNUM *g, DH *dh, * OPENSSL_DH_MAX_MODULUS_BITS, 10000 bits. */ bits = (__u16)uadk_DH_bits(dh); + if (bits == 0) { + fprintf(stderr, "invalid dh bits %u\n", bits); + return UADK_P_FAIL; + } + ret = check_dh_bit_useful(bits); - if (!ret) { - fprintf(stderr, "op size is not supported by uadk engine\n"); - return UADK_E_FAIL; + if (ret == UADK_P_FAIL) { + fprintf(stderr, "invalid: dh%u is not supported by uadk provider\n", bits); + return UADK_P_FAIL; }
- *dh_sess = dh_get_eng_session(dh, bits, is_g2); - if (!(*dh_sess)) { - fprintf(stderr, "failed to get eng ctx\n"); - return UADK_E_FAIL; + *dh_sess = uadk_prov_dh_new_session(dh, bits, is_g2); + if (*dh_sess == NULL) { + fprintf(stderr, "failed to get session\n"); + return UADK_P_FAIL; }
- ret = dh_try_get_priv_key(*dh_sess, dh, priv_key); - if (!ret) { - dh_free_eng_session(*dh_sess); - return UADK_E_FAIL; + ret = uadk_prov_dh_prepare_prikey(*dh_sess, dh, prikey); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to get private key\n"); + uadk_prov_dh_free_session(*dh_sess); }
return ret; }
+static void uadk_prov_dh_free_prepare_data(struct uadk_dh_sess *dh_sess, BIGNUM *prikey) +{ + uadk_prov_dh_free_prikey(dh_sess, prikey); + uadk_prov_dh_free_session(dh_sess); +} + static int dh_set_g(const BIGNUM *g, const __u16 key_size, - unsigned char *ag_bin, struct uadk_dh_sess *dh_sess) + unsigned char *g_bin, struct uadk_dh_sess *dh_sess) { - struct wd_dtb g_dtb; + struct wd_dtb g_dtb = {0}; __u32 gbytes; int ret;
- gbytes = BN_bn2bin(g, ag_bin); - g_dtb.data = (char *)ag_bin; + gbytes = BN_bn2bin(g, g_bin); + g_dtb.data = (char *)g_bin; g_dtb.bsize = key_size; g_dtb.dsize = gbytes;
ret = wd_dh_set_g(dh_sess->sess, &g_dtb); if (ret) { fprintf(stderr, "failed to set dh g\n"); - return UADK_E_FAIL; + return UADK_P_FAIL; }
- return UADK_E_SUCCESS; + return UADK_P_SUCCESS; }
-static int dh_get_pubkey(struct uadk_dh_sess *dh_sess, BIGNUM **pubkey) +static int uadk_prov_dh_get_pubkey(struct uadk_dh_sess *dh_sess, BIGNUM **pubkey) { const unsigned char *pubkey_str;
pubkey_str = (const unsigned char *)dh_sess->req.pri; - if (!pubkey_str) - return UADK_E_FAIL; + if (pubkey_str == NULL) { + fprintf(stderr, "dh_sess->req.pri is NULL\n"); + return UADK_P_FAIL; + }
*pubkey = BN_bin2bn(pubkey_str, dh_sess->req.pri_bytes, *pubkey); - if (!(*pubkey)) - return UADK_E_FAIL; + if (*pubkey == NULL) { + fprintf(stderr, "failed to trans pubkey outs\n"); + return UADK_P_FAIL; + }
- return UADK_E_SUCCESS; + return UADK_P_SUCCESS; }
-static int dh_fill_genkey_req(const BIGNUM *g, const BIGNUM *p, - const BIGNUM *priv_key, - struct uadk_dh_sess *dh_sess) +static int uadk_prov_dh_fill_genkey_req(const BIGNUM *g, const BIGNUM *p, const BIGNUM *prikey, + struct uadk_dh_sess *dh_sess) { + unsigned char *g_bin, *x_bin, *p_bin, *pri_bin; __u16 key_size = dh_sess->key_size; - unsigned char *apriv_key_bin; - unsigned char *ag_bin; - unsigned char *ap_bin; - unsigned char *out_pri; - int ret;
- ag_bin = OPENSSL_malloc(key_size); - if (!ag_bin) - return UADK_E_FAIL; - - /* Malloc a contiguous chunk of memory */ - apriv_key_bin = OPENSSL_malloc(key_size * DH_PARAMS_CNT); - if (!apriv_key_bin) - goto free_ag; + g_bin = OPENSSL_zalloc(key_size); + if (g_bin == NULL) { + fprintf(stderr, "failed to alloc g_bin\n"); + return UADK_P_FAIL; + }
- ap_bin = apriv_key_bin + key_size; - out_pri = ap_bin + key_size; - memset(ag_bin, 0, key_size); - memset(apriv_key_bin, 0, key_size); - memset(ap_bin, 0, key_size); - memset(out_pri, 0, key_size); + /* x is private key, x and p will be treated together in uadk */ + x_bin = OPENSSL_zalloc(key_size * DH_PARAMS_CNT); + if (x_bin == NULL) { + fprintf(stderr, "failed to alloc x_bin\n"); + goto free_g; + } + p_bin = x_bin + key_size; + pri_bin = p_bin + key_size;
/* Construct data block of g */ - ret = dh_set_g(g, key_size, ag_bin, dh_sess); - if (!ret) - goto free_apriv; + if (dh_set_g(g, key_size, g_bin, dh_sess) == UADK_P_FAIL) + goto free_x_p_pri;
- dh_sess->req.xbytes = BN_bn2bin(priv_key, apriv_key_bin); - dh_sess->req.pbytes = BN_bn2bin(p, ap_bin); - dh_sess->req.x_p = (void *)apriv_key_bin; - dh_sess->req.pri = out_pri; + dh_sess->req.xbytes = BN_bn2bin(prikey, x_bin); + dh_sess->req.pbytes = BN_bn2bin(p, p_bin); + dh_sess->req.x_p = (void *)x_bin; + dh_sess->req.pri = pri_bin; dh_sess->req.pri_bytes = key_size; dh_sess->req.op_type = WD_DH_PHASE1;
- OPENSSL_free(ag_bin); + /* Free binary g right away, free other parameters later */ + OPENSSL_free(g_bin);
- return ret; + return UADK_P_SUCCESS; + +free_x_p_pri: + OPENSSL_free(x_bin); +free_g: + OPENSSL_free(g_bin);
-free_apriv: - OPENSSL_free(apriv_key_bin); -free_ag: - OPENSSL_free(ag_bin); - return UADK_E_FAIL; + return UADK_P_FAIL; }
-static int dh_fill_compkey_req(const BIGNUM *g, const BIGNUM *p, - const BIGNUM *priv_key, const BIGNUM *pub_key, - struct uadk_dh_sess *dh_sess) +static void uadk_prov_dh_free_genkey_req(struct uadk_dh_sess *dh_sess) { - __u16 key_size = dh_sess->key_size; - unsigned char *apriv_key_bin; - unsigned char *ap_bin; - unsigned char *ag_bin; - unsigned char *out_pri; - int ret; - - ag_bin = OPENSSL_malloc(key_size); - if (!ag_bin) - return UADK_E_FAIL; - - apriv_key_bin = OPENSSL_malloc(key_size * DH_PARAMS_CNT); - if (!apriv_key_bin) - goto free_ag; - - ap_bin = apriv_key_bin + key_size; - out_pri = ap_bin + key_size; - memset(ag_bin, 0, key_size); - memset(apriv_key_bin, 0, key_size); - memset(ap_bin, 0, key_size); - memset(out_pri, 0, key_size); - - ret = dh_set_g(g, key_size, ag_bin, dh_sess); - if (!ret) - goto free_apriv; - - dh_sess->req.x_p = apriv_key_bin; - dh_sess->req.xbytes = BN_bn2bin(priv_key, apriv_key_bin); - dh_sess->req.pbytes = BN_bn2bin(p, ap_bin); - - dh_sess->req.pv = ag_bin; - dh_sess->req.pvbytes = BN_bn2bin(pub_key, ag_bin); - dh_sess->req.pri = out_pri; - dh_sess->req.pri_bytes = key_size; - dh_sess->req.op_type = WD_DH_PHASE2; - - return ret; + if (dh_sess == NULL) + return;
-free_apriv: - OPENSSL_free(apriv_key_bin); -free_ag: - OPENSSL_free(ag_bin); - return UADK_E_FAIL; + /* Free x_bin, p_bin and pri_bin */ + if (dh_sess->req.x_p) + OPENSSL_free(dh_sess->req.x_p); }
-static int dh_do_crypto(struct uadk_dh_sess *dh_sess) +static int uadk_prov_dh_do_crypto(struct uadk_dh_sess *dh_sess) { struct uadk_e_cb_info cb_param; struct async_op op; - int idx, ret; + int idx, ret, cnt;
ret = async_setup_async_event_notification(&op); - if (!ret) { + if (ret == 0) { printf("failed to setup async event notification.\n"); - return UADK_E_FAIL; + return UADK_P_FAIL; }
- if (!op.job) { + if (op.job == NULL) { ret = wd_do_dh_sync(dh_sess->sess, &dh_sess->req); if (ret) - return UADK_E_FAIL; + return UADK_P_FAIL; } else { cb_param.op = &op; cb_param.priv = &dh_sess->req; @@ -927,12 +842,17 @@ static int dh_do_crypto(struct uadk_dh_sess *dh_sess) goto err;
op.idx = idx; - + cnt = 0; do { ret = wd_do_dh_async(dh_sess->sess, &dh_sess->req); if (ret < 0 && ret != -EBUSY) { - async_free_poll_task(idx, 0); - goto err; + fprintf(stderr, "failed to do dh async\n"); + goto free_poll_task; + } + + if (unlikely(++cnt > PROV_SEND_MAX_CNT)) { + fprintf(stderr, "do dh async operation timeout\n"); + goto free_poll_task; } } while (ret == -EBUSY);
@@ -945,929 +865,1198 @@ static int dh_do_crypto(struct uadk_dh_sess *dh_sess) goto err; }
- return UADK_E_SUCCESS; + return UADK_P_SUCCESS;
+free_poll_task: + async_free_poll_task(idx, 0); err: (void)async_clear_async_event_notification(); - return UADK_E_FAIL; + return UADK_P_FAIL; }
-static int dh_soft_set_pkey(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) +static int uadk_prov_dh_set_pkey(DH *dh, BIGNUM *pubkey, BIGNUM *prikey) { - const BIGNUM *old_pub = uadk_DH_get0_pub_key(dh); const BIGNUM *old_priv = uadk_DH_get0_priv_key(dh); + const BIGNUM *old_pub = uadk_DH_get0_pub_key(dh); + int ret = UADK_P_SUCCESS;
- if (old_pub != pub_key && old_priv != priv_key) - uadk_DH_set0_key(dh, pub_key, priv_key); - else if (old_pub != pub_key) - uadk_DH_set0_key(dh, pub_key, NULL); - else if (old_priv != priv_key) - uadk_DH_set0_key(dh, NULL, priv_key); + if (old_pub != pubkey && old_priv != prikey) + ret = uadk_DH_set0_key(dh, pubkey, prikey); + else if (old_pub != pubkey) + ret = uadk_DH_set0_key(dh, pubkey, NULL); + else if (old_priv != prikey) + ret = uadk_DH_set0_key(dh, NULL, prikey);
- return UADK_E_SUCCESS; + return ret; }
-static int uadk_dh_generate_key(DH *dh) +static int uadk_prov_dh_generate_key(DH *dh) { struct uadk_dh_sess *dh_sess = NULL; - BIGNUM *priv_key = NULL; - BIGNUM *pub_key = NULL; const BIGNUM *p = NULL; const BIGNUM *g = NULL; - const BIGNUM *q = NULL; + BIGNUM *prikey = NULL; + BIGNUM *pubkey = NULL; int ret;
- if (!dh) - goto exe_soft; + if (dh == NULL) { + fprintf(stderr, "invalid: dh is NULL\n"); + return UADK_P_FAIL; + }
ret = uadk_prov_dh_init(); - if (ret) - goto exe_soft; + if (ret) { + fprintf(stderr, "failed to init dh\n"); + return UADK_P_FAIL; + }
- uadk_DH_get0_pqg(dh, &p, &q, &g); - if (!p || !g || q) - goto exe_soft; + uadk_DH_get0_pqg(dh, &p, NULL, &g); + if (p == NULL || g == NULL) { + fprintf(stderr, "invalid: p or g is NULL\n"); + return UADK_P_FAIL; + }
/* Get session and prepare private key */ - ret = dh_prepare_data(g, dh, &dh_sess, &priv_key); - if (!ret) { - fprintf(stderr, "prepare dh data failed\n"); - goto exe_soft; + ret = uadk_prov_dh_prepare_data(g, dh, &dh_sess, &prikey); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to prepare dh data\n"); + return ret; }
- ret = dh_fill_genkey_req(g, p, priv_key, dh_sess); - if (!ret) { + ret = uadk_prov_dh_fill_genkey_req(g, p, prikey, dh_sess); + if (ret == UADK_P_FAIL) { fprintf(stderr, "failed to fill req\n"); goto free_data; }
- ret = dh_do_crypto(dh_sess); - if (!ret) { + ret = uadk_prov_dh_do_crypto(dh_sess); + if (ret == UADK_P_FAIL) { fprintf(stderr, "failed to generate DH key\n"); - goto free_data; + goto free_req; }
- ret = dh_get_pubkey(dh_sess, &pub_key); - if (!ret) { + ret = uadk_prov_dh_get_pubkey(dh_sess, &pubkey); + if (ret == UADK_P_FAIL) { fprintf(stderr, "failed to get public key\n"); - goto free_data; + goto free_req; }
- ret = dh_soft_set_pkey(dh, pub_key, priv_key); - dh_free_eng_session(dh_sess); + ret = uadk_prov_dh_set_pkey(dh, pubkey, prikey); + if (ret == UADK_P_FAIL) + fprintf(stderr, "failed to set dh pkey\n"); + + uadk_prov_dh_free_genkey_req(dh_sess); + uadk_prov_dh_free_session(dh_sess);
return ret;
+free_req: + uadk_prov_dh_free_genkey_req(dh_sess); free_data: - if (dh_sess->key_flag == KEY_GEN_BY_ENGINE) - BN_free(priv_key); - dh_free_eng_session(dh_sess); -exe_soft: - fprintf(stderr, "switch to execute openssl software calculation.\n"); - return UADK_DO_SOFT; + uadk_prov_dh_free_prepare_data(dh_sess, prikey); + + return UADK_P_FAIL; }
-static int uadk_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, - DH *dh) +static int dh_gencb(int p, int n, BN_GENCB *cb) { - struct uadk_dh_sess *dh_sess = NULL; - BIGNUM *priv_key = NULL; - const BIGNUM *p = NULL; - const BIGNUM *g = NULL; - const BIGNUM *q = NULL; - int ret; + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END }; + PROV_DH_KEYMGMT_CTX *gctx = BN_GENCB_get_arg(cb);
- if (!dh || !key || !pub_key || !uadk_DH_get0_priv_key(dh)) - goto exe_soft; + params[0] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_POTENTIAL, &p); + params[1] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_ITERATION, &n);
- ret = uadk_prov_dh_init(); - if (ret) - goto exe_soft; + return gctx->cb(params, gctx->cbarg); +}
- uadk_DH_get0_pqg(dh, &p, &q, &g); - if (!p || !g) - goto exe_soft; +static int ossl_dh_get_named_group_uid_from_size(int pbits) +{ + int nid;
- ret = dh_prepare_data(g, dh, &dh_sess, &priv_key); - if (!ret) { - fprintf(stderr, "failed to prepare dh data\n"); - goto exe_soft; + /* + * Just choose an approved safe prime group. + * The alternative to this is to generate FIPS186-4 domain parameters i.e. + * return dh_generate_ffc_parameters(ret, prime_len, 0, NULL, cb); + * As the FIPS186-4 generated params are for backwards compatibility, + * the safe prime group should be used as the default. + */ + switch (pbits) { + case DH2048BITS: + nid = NID_ffdhe2048; + break; + case DH3072BITS: + nid = NID_ffdhe3072; + break; + case DH4096BITS: + nid = NID_ffdhe4096; + break; + /* + * Retain the commonly supported part. The different specifications are + * listed in the unsupported prime_len scope: + * 'pbits' 6144 and 8192 are supported by OpenSSL but not supported by uadk, + * 'pbits' 768/1024/1536 are not supported by OpenSSL. + * + */ + default: + return NID_undef; }
- ret = dh_fill_compkey_req(g, p, priv_key, pub_key, dh_sess); - if (!ret) { - fprintf(stderr, "failed to fill req\n"); - goto free_data; - } + return nid; +}
- ret = dh_do_crypto(dh_sess); - if (!ret) { - fprintf(stderr, "failed to generate DH shared key\n"); - goto free_data; - } +static int ossl_dh_generate_ffc_parameters(DH *dh, int type, int pbits, int qbits, + BN_GENCB *cb) +{ + int ret, res;
- memcpy(key, dh_sess->req.pri, dh_sess->req.pri_bytes); - ret = dh_sess->req.pri_bytes; - dh_free_eng_session(dh_sess); + if (type == DH_PARAMGEN_TYPE_FIPS_186_2) + ret = ossl_ffc_params_FIPS186_2_generate(dh->libctx, &dh->params, + FFC_PARAM_TYPE_DH, pbits, qbits, &res, cb); + else + ret = ossl_ffc_params_FIPS186_4_generate(dh->libctx, &dh->params, + FFC_PARAM_TYPE_DH, pbits, qbits, &res, cb); + if (ret > 0) + dh->dirty_cnt++;
return ret; - -free_data: - if (dh_sess->key_flag == KEY_GEN_BY_ENGINE) - BN_free(priv_key); - dh_free_eng_session(dh_sess); -exe_soft: - fprintf(stderr, "switch to execute openssl software calculation.\n"); - return UADK_DO_SOFT; }
-static void uadk_ffc_params_init(FFC_PARAMS *params) +static DH *ossl_dh_new_ex(OSSL_LIB_CTX *libctx) { - memset(params, 0, sizeof(*params)); - params->pcounter = -1; - params->gindex = FFC_UNVERIFIABLE_GINDEX; - params->flags = FFC_PARAM_FLAG_VALIDATE_PQG; + DH *dh = OPENSSL_zalloc(sizeof(*dh)); + + if (dh == NULL) { + fprintf(stderr, "failed to alloc dh\n"); + return NULL; + } + + dh->references = 1; + dh->lock = CRYPTO_THREAD_lock_new(); + if (dh->lock == NULL) { + fprintf(stderr, "failed to new dh thread lock\n"); + OPENSSL_free(dh); + return NULL; + } + + dh->libctx = libctx; + + return dh; }
-static void uadk_ffc_params_cleanup(FFC_PARAMS *params) +static void ossl_dh_free_ex(DH *dh) { - BN_free(params->p); - BN_free(params->q); - BN_free(params->g); - BN_free(params->j); - OPENSSL_free(params->seed); - uadk_ffc_params_init(params); + if (dh) { + CRYPTO_THREAD_lock_free(dh->lock); + OPENSSL_free(dh); + } }
-static void uadk_DH_free(DH *r) +static DH *uadk_prov_dh_gen_params_with_group(PROV_DH_KEYMGMT_CTX *gctx, FFC_PARAMS **ffc) { - int i; - - if (r == NULL) - return; - - CRYPTO_DOWN_REF(&r->references, &i, r->lock); - if (i > 0) - return; + const DH_NAMED_GROUP *group = NULL; + DH *dh = NULL;
- if (i < 0) - fprintf(stderr, "WARN: refcount error.\n"); + /* Select a named group if there is not one already */ + if (gctx->group_nid == NID_undef) + gctx->group_nid = ossl_dh_get_named_group_uid_from_size(gctx->pbits); + if (gctx->group_nid == NID_undef) { + fprintf(stderr, "failed to get named group uid from size\n"); + return NULL; + }
- if (r->meth != NULL && r->meth->finish != NULL) - r->meth->finish(r); + group = ossl_ffc_uid_to_dh_named_group(gctx->group_nid); + if (group) { + dh = ossl_dh_new_ex(gctx->libctx); + if (dh == NULL) { + fprintf(stderr, "failed to get dh from libctx\n"); + return NULL; + }
- CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, r, &r->ex_data); + ossl_ffc_named_group_set(&dh->params, group); + dh->params.nid = ossl_ffc_named_group_get_uid(group); + dh->dirty_cnt++; + }
- CRYPTO_THREAD_lock_free(r->lock); + *ffc = ossl_dh_get0_params(dh); + if (*ffc == NULL) { + fprintf(stderr, "failed to gen ffc params\n"); + ossl_dh_free_ex(dh); + return NULL; + }
- uadk_ffc_params_cleanup(&r->params); - BN_clear_free(r->pub_key); - BN_clear_free(r->priv_key); - OPENSSL_free(r); + return dh; }
-static void *uadk_dh_keyexch_newctx(void *provctx) +static DH *uadk_prov_dh_gen_params_ex(PROV_DH_KEYMGMT_CTX *gctx, FFC_PARAMS **ffc) { - UADK_PROV_DH_CTX *pdhctx; + DH *dh = NULL;
- pdhctx = OPENSSL_zalloc(sizeof(UADK_PROV_DH_CTX)); - if (pdhctx == NULL) + /* Use existing params */ + dh = ossl_dh_new_ex(gctx->libctx); + if (dh == NULL) { + fprintf(stderr, "failed to new dh by nid\n"); return NULL; - pdhctx->libctx = prov_libctx_of(provctx); - pdhctx->kdf_type = PROV_DH_KDF_NONE; - return pdhctx; -} + }
-/* The 2 parties must share the same domain parameters */ -static int uadk_dh_keyexch_match_params(DH *priv, DH *peer) -{ - int ret; - FFC_PARAMS *dhparams_priv = uadk_dh_get0_params(priv); - FFC_PARAMS *dhparams_peer = uadk_dh_get0_params(peer); + *ffc = ossl_dh_get0_params(dh); + if (*ffc == NULL) { + fprintf(stderr, "failed to get ffc params\n"); + goto free_dh; + }
- ret = dhparams_priv != NULL && dhparams_peer != NULL && - uadk_ffc_params_cmp(dhparams_priv, dhparams_peer, 1); - if (!ret) - ERR_raise(ERR_LIB_PROV, PROV_R_MISMATCHING_DOMAIN_PARAMETERS); - return ret; -} + /* Copy the template value if one was passed */ + if (gctx->ffc_params != NULL && ossl_ffc_params_copy(*ffc, gctx->ffc_params) == 0) { + fprintf(stderr, "failed to copy params\n"); + goto free_dh; + }
-static int uadk_dh_keyexch_set_peer(void *vpdhctx, void *vdh) -{ - UADK_PROV_DH_CTX *pdhctx = (UADK_PROV_DH_CTX *)vpdhctx; + if (ossl_ffc_params_set_seed(*ffc, gctx->seed, gctx->seedlen) == 0) { + fprintf(stderr, "failed to set seed\n"); + goto free_dh; + }
- if (pdhctx == NULL || vdh == NULL || - !uadk_dh_keyexch_match_params(vdh, pdhctx->dh) || - !uadk_DH_up_ref(vdh)) - return 0; - uadk_DH_free(pdhctx->dhpeer); - pdhctx->dhpeer = vdh; - return 1; + if (gctx->gindex != -1) { + ossl_ffc_params_set_gindex(*ffc, gctx->gindex); + if (gctx->pcounter != -1) + ossl_ffc_params_set_pcounter(*ffc, gctx->pcounter); + } else if (gctx->hindex != 0) { + ossl_ffc_params_set_h(*ffc, gctx->hindex); + } + + if (gctx->mdname) { + if (ossl_ffc_set_digest(*ffc, gctx->mdname, gctx->mdprops) == 0) { + fprintf(stderr, "failed to set digest\n"); + goto free_dh; + } + } + + return dh; + +free_dh: + ossl_dh_free_ex(dh); + + return NULL; }
-static int uadk_dh_plain_derive(void *vpdhctx, unsigned char *secret, - size_t *secretlen, size_t outlen) +static int uadk_prov_dh_gen_params_cb(PROV_DH_KEYMGMT_CTX *gctx, DH *dh, + OSSL_CALLBACK *cb, void *cb_params, BN_GENCB *gencb) { - UADK_PROV_DH_CTX *pdhctx = (UADK_PROV_DH_CTX *)vpdhctx; - const BIGNUM *pub_key = NULL; - size_t dhsize; int ret;
- if (pdhctx->dh == NULL || pdhctx->dhpeer == NULL) { - ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY); - return 0; + if (cb == NULL || cb_params == NULL) { + fprintf(stderr, "invalid: cb function or param is NULL\n"); + return UADK_P_FAIL; }
- dhsize = (size_t)uadk_DH_size(pdhctx->dh); - if (secret == NULL) { - *secretlen = dhsize; - return 1; + gctx->cb = cb; + gctx->cbarg = cb_params; + /* gencb can be NULL */ + gencb = BN_GENCB_new(); + if (gencb != NULL) + BN_GENCB_set(gencb, dh_gencb, gctx); + + if ((gctx->selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { + /* + * NOTE: The old safe prime generator code is not used in fips mode, + * (i.e internally it ignores the generator and chooses a named + * group based on pbits. + */ + if (gctx->gen_type == DH_PARAMGEN_TYPE_GENERATOR) + ret = DH_generate_parameters_ex(dh, gctx->pbits, + gctx->generator, gencb); + else + ret = ossl_dh_generate_ffc_parameters(dh, gctx->gen_type, + gctx->pbits, gctx->qbits, gencb); + if (ret <= 0) { + fprintf(stderr, "failed to generate ffc parameters\n"); + goto free_cb; + } }
- if (outlen < dhsize) { - ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); - return 0; - } + return UADK_P_SUCCESS;
- uadk_DH_get0_key(pdhctx->dhpeer, &pub_key, NULL); +free_cb: + if (gencb) + BN_GENCB_free(gencb);
- ret = uadk_dh_compute_key(secret, pub_key, pdhctx->dh); - if (ret <= 0) - return ret; + return UADK_P_FAIL; +}
- *secretlen = ret; - return 1; +static void uadk_prov_dh_free_params_cb(BN_GENCB *gencb) +{ + if (gencb) + BN_GENCB_free(gencb); } -static int uadk_dh_keyexch_derive(void *vpdhctx, unsigned char *secret, - size_t *psecretlen, size_t outlen) + +static DH *uadk_prov_dh_gen_params(PROV_DH_KEYMGMT_CTX *gctx, FFC_PARAMS **ffc, + OSSL_CALLBACK *cb, void *cb_params, BN_GENCB *gencb) { - typedef int (*fun_ptr)(void *vpdhctx, unsigned char *secret, - size_t *secretlen, size_t outlen); - UADK_PROV_DH_CTX *pdhctx = (UADK_PROV_DH_CTX *)vpdhctx; - int ret = 0; + DH *dh = NULL; + int ret;
- switch (pdhctx->kdf_type) { - case PROV_DH_KDF_NONE: - ret = uadk_dh_plain_derive(pdhctx, secret, psecretlen, outlen); - if (ret == UADK_DO_SOFT) - goto exec_soft; - default: - break; + /* For parameter generation - If there is a group name just create it */ + if (gctx->gen_type == DH_PARAMGEN_TYPE_GROUP && gctx->ffc_params == NULL) { + dh = uadk_prov_dh_gen_params_with_group(gctx, ffc); + if (dh == NULL || *ffc == NULL) + return NULL; + } else { + dh = uadk_prov_dh_gen_params_ex(gctx, ffc); + if (dh == NULL || *ffc == NULL) + return NULL; + + ret = uadk_prov_dh_gen_params_cb(gctx, dh, cb, cb_params, gencb); + if (ret == UADK_P_FAIL) { + ossl_dh_free_ex(dh); + return NULL; + } } - return ret;
-exec_soft: - fprintf(stderr, "switch to execute openssl software calculation.\n"); - fun_ptr fun = get_default_keyexch().derive; - - if (!fun) - return 0; - - return fun(vpdhctx, secret, psecretlen, outlen); + return dh; }
-static void uadk_dh_keyexch_freectx(void *vpdhctx) +static void uadk_prov_dh_free_params(DH *dh, BN_GENCB *gencb) { - UADK_PROV_DH_CTX *pdhctx = (UADK_PROV_DH_CTX *)vpdhctx; - - OPENSSL_free(pdhctx->kdf_cekalg); - uadk_DH_free(pdhctx->dh); - uadk_DH_free(pdhctx->dhpeer); - EVP_MD_free(pdhctx->kdf_md); - OPENSSL_clear_free(pdhctx->kdf_ukm, pdhctx->kdf_ukmlen); - OPENSSL_free(pdhctx); + /* + * Release DH object that allocated by uadk_prov_dh_gen_params_ex() or + * uadk_prov_dh_gen_params_with_group(). + */ + ossl_dh_free_ex(dh); + uadk_prov_dh_free_params_cb(gencb); }
-static void *uadk_dh_keyexch_dupctx(void *vpdhctx) +static void *uadk_keymgmt_dh_gen(void *genctx, OSSL_CALLBACK *cb, void *cb_params) { - UADK_PROV_DH_CTX *srcctx = (UADK_PROV_DH_CTX *)vpdhctx; - UADK_PROV_DH_CTX *dstctx; + PROV_DH_KEYMGMT_CTX *gctx = (PROV_DH_KEYMGMT_CTX *)genctx; + BN_GENCB *gencb = NULL; + FFC_PARAMS *ffc = NULL; + DH *dh = NULL; + int ret;
- dstctx = OPENSSL_zalloc(sizeof(*srcctx)); - if (dstctx == NULL) + if (gctx == NULL) { + fprintf(stderr, "invalid: keygen ctx is NULL\n"); return NULL; + }
- *dstctx = *srcctx; - dstctx->dh = NULL; - dstctx->dhpeer = NULL; - dstctx->kdf_md = NULL; - dstctx->kdf_ukm = NULL; - dstctx->kdf_cekalg = NULL; + /* + * If a group name is selected then the type is group regardless of what + * the user selected. This overrides rather than errors for backwards + * compatibility. + */ + if (gctx->group_nid != NID_undef) + gctx->gen_type = DH_PARAMGEN_TYPE_GROUP;
- if (srcctx->dh != NULL && !uadk_DH_up_ref(srcctx->dh)) - goto err; - else - dstctx->dh = srcctx->dh; + dh = uadk_prov_dh_gen_params(gctx, &ffc, cb, cb_params, gencb); + if (dh == NULL || ffc == NULL) + return NULL;
- if (srcctx->dhpeer != NULL && !uadk_DH_up_ref(srcctx->dhpeer)) - goto err; - else - dstctx->dhpeer = srcctx->dhpeer; + /* DH key generation */ + if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { + if (ffc->p == NULL || ffc->g == NULL) { + fprintf(stderr, "invalid: ffc->p or ffc->g is NULL\n"); + goto free_gen_params; + }
- if (srcctx->kdf_md != NULL && !EVP_MD_up_ref(srcctx->kdf_md)) - goto err; - else - dstctx->kdf_md = srcctx->kdf_md; + if (gctx->priv_len > 0) + (void)DH_set_length(dh, (long)gctx->priv_len);
- /* Duplicate UKM data if present */ - if (srcctx->kdf_ukm != NULL && srcctx->kdf_ukmlen > 0) { - dstctx->kdf_ukm = OPENSSL_memdup(srcctx->kdf_ukm, - srcctx->kdf_ukmlen); - if (dstctx->kdf_ukm == NULL) - goto err; - } + ossl_ffc_params_enable_flags(ffc, FFC_PARAM_FLAG_VALIDATE_LEGACY, + gctx->gen_type == DH_PARAMGEN_TYPE_FIPS_186_2);
- if (srcctx->kdf_cekalg != NULL) { - dstctx->kdf_cekalg = OPENSSL_strdup(srcctx->kdf_cekalg); - if (dstctx->kdf_cekalg == NULL) - goto err; + ret = uadk_prov_dh_generate_key(dh); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to do dh generation key\n"); + goto free_gen_params; + } }
- return dstctx; -err: - uadk_dh_keyexch_freectx(dstctx); + uadk_DH_clear_flags(dh, DH_FLAG_TYPE_MASK); + uadk_DH_set_flags(dh, gctx->dh_type); + uadk_prov_dh_free_params_cb(gencb); + + return dh; + +free_gen_params: + uadk_prov_dh_free_params(dh, gencb); return NULL; }
-static int uadk_dh_keyexch_set_ctx_params(void *vpdhctx, - const OSSL_PARAM params[]) +static int uadk_DH_size(const DH *dh) { - UADK_PROV_DH_CTX *pdhctx = (UADK_PROV_DH_CTX *)vpdhctx; - const OSSL_PARAM *p; - unsigned int pad; - char name[80] = {'\0'}; /* should be big enough */ - char *str = NULL; + /* DH object has been checked when the function is called */ + if (dh->params.p != NULL) + return BN_num_bytes(dh->params.p);
- if (pdhctx == NULL) - return 0; - if (params == NULL) - return 1; + /* size zero */ + return 0; +}
- p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_TYPE); - if (p != NULL) { - str = name; - if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name))) - return 0; +static void uadk_DH_get0_key(const DH *dh, const BIGNUM **pubkey, + const BIGNUM **prikey) +{ + /* DH object has been checked when the function is called */ + if (pubkey != NULL) + *pubkey = dh->pub_key;
- if (name[0] == '\0') - pdhctx->kdf_type = PROV_DH_KDF_NONE; - else if (strcmp(name, OSSL_KDF_NAME_X942KDF_ASN1) == 0) - pdhctx->kdf_type = PROV_DH_KDF_X9_42_ASN1; - else - return 0; - } - p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST); - if (p != NULL) { - char mdprops[80] = {'\0'}; /* should be big enough */ + if (prikey != NULL) + *prikey = dh->priv_key; +}
- str = name; - if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name))) - return 0; +static void *uadk_keyexch_dh_newctx(void *provctx) +{ + PROV_DH_KEYEXCH_CTX *pdhctx;
- str = mdprops; - p = OSSL_PARAM_locate_const(params, - OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS); + pdhctx = OPENSSL_zalloc(sizeof(PROV_DH_KEYEXCH_CTX)); + if (pdhctx == NULL) { + fprintf(stderr, "failed to alloc pdhctx\n"); + return NULL; + }
- if (p != NULL) - if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdprops))) - return 0; + /* The libctx maybe NULL, if libctx is NULL, will use default ctx. */ + pdhctx->libctx = prov_libctx_of(provctx); + pdhctx->kdf_type = PROV_DH_KDF_NONE;
- EVP_MD_free(pdhctx->kdf_md); - pdhctx->kdf_md = EVP_MD_fetch(pdhctx->libctx, name, mdprops); + return pdhctx; +}
- if (pdhctx->kdf_md == NULL) - return 0; - } +static void uadk_keyexch_dh_freectx(void *dhctx) +{ + PROV_DH_KEYEXCH_CTX *pdhctx = (PROV_DH_KEYEXCH_CTX *)dhctx;
- p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN); - if (p != NULL) { - size_t outlen; + if (pdhctx == NULL) + return;
- if (!OSSL_PARAM_get_size_t(p, &outlen)) - return 0; - pdhctx->kdf_outlen = outlen; + if (pdhctx->kdf_cekalg) { + OPENSSL_free(pdhctx->kdf_cekalg); + pdhctx->kdf_cekalg = NULL; }
- p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_UKM); - if (p != NULL) { - void *tmp_ukm = NULL; - size_t tmp_ukmlen; + if (pdhctx->dh) { + DH_free(pdhctx->dh); + pdhctx->dh = NULL; + }
- OPENSSL_free(pdhctx->kdf_ukm); - pdhctx->kdf_ukm = NULL; - pdhctx->kdf_ukmlen = 0; - /* ukm is an optional field so it can be NULL */ - if (p->data != NULL && p->data_size != 0) { - if (!OSSL_PARAM_get_octet_string(p, &tmp_ukm, 0, &tmp_ukmlen)) - return 0; - pdhctx->kdf_ukm = tmp_ukm; - pdhctx->kdf_ukmlen = tmp_ukmlen; - } + if (pdhctx->dhpeer) { + DH_free(pdhctx->dhpeer); + pdhctx->dhpeer = NULL; }
- p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_PAD); - if (p != NULL) { - if (!OSSL_PARAM_get_uint(p, &pad)) - return 0; - pdhctx->pad = pad ? 1 : 0; + if (pdhctx->kdf_md) { + EVP_MD_free(pdhctx->kdf_md); + pdhctx->kdf_md = NULL; }
- p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_CEK_ALG); - if (p != NULL) { - str = name; + if (pdhctx->kdf_ukm) { + OPENSSL_clear_free(pdhctx->kdf_ukm, pdhctx->kdf_ukmlen); + pdhctx->kdf_ukm = NULL; + }
+ if (pdhctx->kdf_cekalg) { OPENSSL_free(pdhctx->kdf_cekalg); pdhctx->kdf_cekalg = NULL; - if (p->data != NULL && p->data_size != 0) { - if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name))) - return 0; - pdhctx->kdf_cekalg = OPENSSL_strdup(name); - if (pdhctx->kdf_cekalg == NULL) - return 0; - } } - return 1; -}
-static const OSSL_PARAM known_settable_ctx_params[] = { - OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_PAD, NULL), - OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0), - OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0), - OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS, NULL, 0), - OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL), - OSSL_PARAM_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM, NULL, 0), - OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0), - OSSL_PARAM_END -}; + OPENSSL_free(pdhctx); +}
-static const -OSSL_PARAM *uadk_dh_keyexch_settable_ctx_params(ossl_unused void *vpdhctx, - ossl_unused void *provctx) +static int uadk_keyexch_dh_init(void *dhctx, void *dh, const OSSL_PARAM params[]) { - return known_settable_ctx_params; -} + PROV_DH_KEYEXCH_CTX *pdhctx = (PROV_DH_KEYEXCH_CTX *)dhctx;
-static const OSSL_PARAM known_gettable_ctx_params[] = { - OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0), - OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0), - OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL), - OSSL_PARAM_DEFN(OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_PTR, - NULL, 0), - OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0), - OSSL_PARAM_END -}; + if (pdhctx == NULL) { + fprintf(stderr, "invalid: dhctx is NULL\n"); + return UADK_P_FAIL; + }
-static const -OSSL_PARAM *uadk_dh_keyexch_gettable_ctx_params(ossl_unused void *vpdhctx, - ossl_unused void *provctx) + if (dh == NULL || !DH_up_ref(dh)) { + fprintf(stderr, "invalid: dh is NULL\n"); + return UADK_P_FAIL; + } + + pthread_mutex_lock(&dh_mutex); + if (pdhctx->dh) { + DH_free(pdhctx->dh); + pdhctx->dh = NULL; + } + + pdhctx->dh = dh; + pdhctx->kdf_type = PROV_DH_KDF_NONE; + pthread_mutex_unlock(&dh_mutex); + + return uadk_keyexch_dh_set_ctx_params(pdhctx, params); +} + +/* The 2 parties must share the same domain parameters */ +static int uadk_keyexch_dh_match_params(DH *priv, DH *peer) { - return known_gettable_ctx_params; + FFC_PARAMS *dhparams_priv = ossl_dh_get0_params(priv); + FFC_PARAMS *dhparams_peer = ossl_dh_get0_params(peer); + int ret; + + if (dhparams_priv == NULL || dhparams_peer == NULL) { + fprintf(stderr, "failed to get dh params\n"); + return UADK_P_FAIL; + } + + ret = ossl_ffc_params_cmp(dhparams_priv, dhparams_peer, IGNORE_Q); + if (ret == UADK_P_FAIL) + fprintf(stderr, "invalid: domain parameters of both parties do not match\n"); + + return ret; }
-static int uadk_dh_keyexch_get_ctx_params(void *vpdhctx, OSSL_PARAM params[]) +static int uadk_keyexch_dh_set_peer(void *dhctx, void *dh) { - UADK_PROV_DH_CTX *pdhctx = (UADK_PROV_DH_CTX *)vpdhctx; - OSSL_PARAM *p; + PROV_DH_KEYEXCH_CTX *pdhctx = (PROV_DH_KEYEXCH_CTX *)dhctx;
- if (pdhctx == NULL) - return 0; + if (pdhctx == NULL || dh == NULL) { + fprintf(stderr, "invalid: dh ctx or object is NULL\n"); + return UADK_P_FAIL; + }
- p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_TYPE); - if (p != NULL) { - const char *kdf_type = NULL; + if (uadk_keyexch_dh_match_params(dh, pdhctx->dh) == UADK_P_FAIL || + DH_up_ref(dh) == UADK_P_FAIL) { + fprintf(stderr, "failed to match dh params\n"); + return UADK_P_FAIL; + }
- switch (pdhctx->kdf_type) { - case PROV_DH_KDF_NONE: - kdf_type = ""; - break; - case PROV_DH_KDF_X9_42_ASN1: - kdf_type = OSSL_KDF_NAME_X942KDF_ASN1; - break; - default: - return 0; - } + pthread_mutex_lock(&dh_mutex); + if (pdhctx->dhpeer) + DH_free(pdhctx->dhpeer); + pdhctx->dhpeer = dh; + pthread_mutex_unlock(&dh_mutex);
- if (!OSSL_PARAM_set_utf8_string(p, kdf_type)) - return 0; + return UADK_P_SUCCESS; +} + +static int uadk_prov_dh_fill_compkey_req(const BIGNUM *g, const BIGNUM *p, + const BIGNUM *prikey, const BIGNUM *pubkey, + struct uadk_dh_sess *dh_sess) +{ + unsigned char *x_bin, *p_bin, *g_bin, *out_pri; + __u16 key_size = dh_sess->key_size; + + g_bin = OPENSSL_zalloc(key_size); + if (g_bin == NULL) { + fprintf(stderr, "failed to alloc g\n"); + return UADK_P_FAIL; }
- p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST); - if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdhctx->kdf_md == NULL - ? "" - : EVP_MD_get0_name(pdhctx->kdf_md))) - return 0; + /* x is private key, x and p will be treated together in uadk */ + x_bin = OPENSSL_zalloc(key_size * DH_PARAMS_CNT); + if (x_bin == NULL) { + fprintf(stderr, "failed to alloc x_bin\n"); + goto free_g; + }
- p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN); - if (p != NULL && !OSSL_PARAM_set_size_t(p, pdhctx->kdf_outlen)) - return 0; + p_bin = x_bin + key_size; + out_pri = p_bin + key_size;
- p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_UKM); - if (p != NULL && !OSSL_PARAM_set_octet_ptr(p, pdhctx->kdf_ukm, pdhctx->kdf_ukmlen)) - return 0; + /* Construct data block of g */ + if (dh_set_g(g, key_size, g_bin, dh_sess) == UADK_P_FAIL) + goto free_priv;
- p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_CEK_ALG); - if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdhctx->kdf_cekalg == NULL - ? "" - : pdhctx->kdf_cekalg)) - return 0; + dh_sess->req.x_p = x_bin; + dh_sess->req.xbytes = BN_bn2bin(prikey, x_bin); + dh_sess->req.pbytes = BN_bn2bin(p, p_bin);
- return 1; -} + dh_sess->req.pv = g_bin; + dh_sess->req.pvbytes = BN_bn2bin(pubkey, g_bin); + dh_sess->req.pri = out_pri; + dh_sess->req.pri_bytes = key_size; + dh_sess->req.op_type = WD_DH_PHASE2;
-static int uadk_dh_keyexch_init(void *vpdhctx, void *vdh, const OSSL_PARAM params[]) -{ - UADK_PROV_DH_CTX *pdhctx = (UADK_PROV_DH_CTX *)vpdhctx; + return UADK_P_SUCCESS;
- if (pdhctx == NULL || vdh == NULL || !uadk_DH_up_ref(vdh)) - return 0; - uadk_DH_free(pdhctx->dh); - pdhctx->dh = vdh; - pdhctx->kdf_type = PROV_DH_KDF_NONE; - return uadk_dh_keyexch_set_ctx_params(pdhctx, params); +free_priv: + OPENSSL_free(x_bin); +free_g: + OPENSSL_free(g_bin); + + return UADK_P_FAIL; }
-static UADK_DH_KEYMGMT get_default_keymgmt(void) +static void uadk_prov_dh_free_compkey_req(struct uadk_dh_sess *dh_sess) { - static UADK_DH_KEYMGMT s_keymgmt; - static int initilazed; + if (dh_sess == NULL) + return;
- if (!initilazed) { - UADK_DH_KEYMGMT *keymgmt = - (UADK_DH_KEYMGMT *)EVP_KEYMGMT_fetch(NULL, "DH", "provider=default"); + /* Free x_bin, p_bin and pri_bin */ + if (dh_sess->req.x_p) { + OPENSSL_free(dh_sess->req.x_p); + dh_sess->req.x_p = NULL; + }
- if (keymgmt) { - s_keymgmt = *keymgmt; - EVP_KEYMGMT_free((EVP_KEYMGMT *)keymgmt); - initilazed = 1; - } else { - fprintf(stderr, "WARN: EVP_KEYMGMT_fetch from default provider failed"); - } + /* Free pv */ + if (dh_sess->req.pv) { + OPENSSL_free(dh_sess->req.pv); + dh_sess->req.pv = NULL; } - return s_keymgmt; }
-static void *uadk_dh_keymgmt_newdata(void *provctx) +static int uadk_dh_compute_key(unsigned char *key, const BIGNUM *pubkey, DH *dh) { - typedef void *(*fun_ptr)(void *); - fun_ptr fun = get_default_keymgmt().new; + struct uadk_dh_sess *dh_sess = NULL; + BIGNUM *prikey = NULL; + const BIGNUM *p = NULL; + const BIGNUM *g = NULL; + int ret;
- if (!fun) - return NULL; - return fun(provctx); -} + if (!dh || !key || !pubkey || !uadk_DH_get0_priv_key(dh)) { + fprintf(stderr, "failed to check key params\n"); + return UADK_P_FAIL; + }
-static void uadk_dh_keymgmt_freedata(void *keydata) -{ - typedef void (*fun_ptr)(void *); - fun_ptr fun = get_default_keymgmt().free; + uadk_DH_get0_pqg(dh, &p, NULL, &g); + if (!p || !g) { + fprintf(stderr, "failed to get p/q/g param\n"); + return UADK_P_FAIL; + }
- if (!fun) - return; - fun(keydata); -} + ret = uadk_prov_dh_init(); + if (ret) { + fprintf(stderr, "failed to init\n"); + return UADK_P_FAIL; + }
-static int uadk_dh_keymgmt_has(const void *keydata, int selection) -{ - typedef int (*fun_ptr)(const void *, int); - fun_ptr fun = get_default_keymgmt().has; + ret = uadk_prov_dh_prepare_data(g, dh, &dh_sess, &prikey); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to prepare dh data\n"); + return ret; + }
- if (!fun) - return 0; - return fun(keydata, selection); -} + ret = uadk_prov_dh_fill_compkey_req(g, p, prikey, pubkey, dh_sess); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to fill req\n"); + goto free_data; + }
-static int uadk_dh_keymgmt_match(const void *keydata1, const void *keydata2, int selection) -{ - typedef int (*fun_ptr)(const void *, const void *, int); - fun_ptr fun = get_default_keymgmt().match; + ret = uadk_prov_dh_do_crypto(dh_sess); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to generate DH shared key\n"); + goto free_req; + }
- if (!fun) - return 0; - return fun(keydata1, keydata2, selection); -} + memcpy(key, dh_sess->req.pri, dh_sess->req.pri_bytes); + ret = dh_sess->req.pri_bytes; + uadk_prov_dh_free_compkey_req(dh_sess); + /* key will be used by user, do not free it here */ + uadk_prov_dh_free_session(dh_sess);
-static int uadk_dh_keymgmt_import(void *keydata, int selection, const OSSL_PARAM params[]) -{ - typedef int (*fun_ptr)(void *, int, const OSSL_PARAM *); - fun_ptr fun = get_default_keymgmt().import; + return ret;
- if (!fun) - return 0; - return fun(keydata, selection, params); +free_req: + uadk_prov_dh_free_compkey_req(dh_sess); +free_data: + uadk_prov_dh_free_prepare_data(dh_sess, prikey); + + return ret; }
-static int uadk_dh_keymgmt_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, - void *cbarg) +static int uadk_dh_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh) { - typedef int (*fun_ptr)(void *, int, OSSL_CALLBACK *, void *); - fun_ptr fun = get_default_keymgmt().export; + size_t dhsize; + int rv, pad; + + /* rv is constant unless compute_key is external */ + rv = uadk_dh_compute_key(key, pub_key, dh); + if (rv <= 0) + return rv; + + dhsize = BN_num_bytes(dh->params.p); + pad = dhsize - rv; + /* pad is constant (zero) unless compute_key is external */ + if (pad > 0) { + memmove(key + pad, key, rv); + memset(key, 0, pad); + }
- if (!fun) - return 0; - return fun(keydata, selection, param_cb, cbarg); + if (pad < 0) { + fprintf(stderr, "invalid: recv key size(%d) > dhsize(%u)", rv, dhsize); + return UADK_P_FAIL; + } + + return rv + pad; }
-static const OSSL_PARAM *uadk_dh_keymgmt_import_types(int selection) +static int uadk_prov_dh_plain_derive(PROV_DH_KEYEXCH_CTX *pdhctx, unsigned char *secret, + size_t *secretlen, size_t outlen, unsigned int pad) { - typedef const OSSL_PARAM *(*fun_ptr)(int); - fun_ptr fun = get_default_keymgmt().import_types; + const BIGNUM *pubkey = NULL; + size_t dhsize; + int ret;
- if (!fun) - return NULL; - return fun(selection); -} + /* pdhctx has been checked when the function is called */ + if (pdhctx->dh == NULL) { + fprintf(stderr, "invalid: dh is NULL\n"); + return UADK_P_FAIL; + }
-static const OSSL_PARAM *uadk_dh_keymgmt_export_types(int selection) -{ - typedef const OSSL_PARAM *(*fun_ptr)(int); - fun_ptr fun = get_default_keymgmt().export_types; + dhsize = (size_t)uadk_DH_size(pdhctx->dh); + if (dhsize == 0) { + fprintf(stderr, "invalid: dhszie is zero\n"); + return UADK_P_FAIL; + }
- if (!fun) - return NULL; - return fun(selection); + if (secret == NULL) { + *secretlen = dhsize; + return UADK_P_SUCCESS; + } + + if (outlen < dhsize) { + fprintf(stderr, "invalid: outlen(%u) < dhsize(%u)\n", outlen, dhsize); + return UADK_P_FAIL; + } + + if (pdhctx->dhpeer == NULL) { + fprintf(stderr, "invalid: dhpeer is NULL\n"); + return UADK_P_FAIL; + } + + uadk_DH_get0_key(pdhctx->dhpeer, &pubkey, NULL); + + if (pad) + ret = uadk_dh_compute_key_padded(secret, pubkey, pdhctx->dh); + else + ret = uadk_dh_compute_key(secret, pubkey, pdhctx->dh); + if (ret <= 0) { + fprintf(stderr, "failed to do dh compute, pad(%d)\n", pad); + return ret; + } + + *secretlen = ret; + + return UADK_P_SUCCESS; }
-static ossl_inline int uadk_dh_keymgmt_get_params(void *key, OSSL_PARAM params[]) +/* Key derivation function from X9.63/SECG */ +int ossl_dh_kdf_X9_42_asn1(unsigned char *out, PROV_DH_KEYEXCH_CTX *pdhctx, + const unsigned char *z, size_t z_len, + const char *propq) { - typedef int (*fun_ptr)(void *, OSSL_PARAM *); - fun_ptr fun = get_default_keymgmt().get_params; + OSSL_LIB_CTX *libctx = pdhctx->libctx; + const char *cek_alg = pdhctx->kdf_cekalg; + const unsigned char *ukm = pdhctx->kdf_ukm; + OSSL_PARAM params[KDF_PARAM_NUM] = {0}; + size_t outlen = pdhctx->kdf_outlen; + size_t ukmlen = pdhctx->kdf_ukmlen; + const EVP_MD *md = pdhctx->kdf_md; + OSSL_PARAM *p = params; + EVP_KDF_CTX *kctx = NULL; + EVP_KDF *kdf = NULL; + const char *mdname; + int ret = 0;
- if (!fun) + kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_X942KDF_ASN1, propq); + if (kdf == NULL) return 0; - return fun(key, params); -}
-static const OSSL_PARAM *uadk_dh_keymgmt_gettable_params(void *provctx) -{ - typedef const OSSL_PARAM *(*fun_ptr)(void *); - fun_ptr fun = get_default_keymgmt().gettable_params; + kctx = EVP_KDF_CTX_new(kdf); + if (kctx == NULL) + goto end;
- if (!fun) - return NULL; - return fun(provctx); -} + mdname = EVP_MD_get0_name(md); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + (char *)mdname, 0); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, + (unsigned char *)z, z_len); + if (ukm != NULL) + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_UKM, + (unsigned char *)ukm, ukmlen);
-static const OSSL_PARAM *uadk_dh_keymgmt_settable_params(void *provctx) -{ - typedef const OSSL_PARAM *(*fun_ptr)(void *); - fun_ptr fun = get_default_keymgmt().settable_params; + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG, + (char *)cek_alg, 0); + *p = OSSL_PARAM_construct_end(); + ret = EVP_KDF_derive(kctx, out, outlen, params) > 0;
- if (!fun) - return NULL; - return fun(provctx); +end: + EVP_KDF_CTX_free(kctx); + EVP_KDF_free(kdf); + + return ret; }
-static int uadk_dh_keymgmt_set_params(void *key, const OSSL_PARAM params[]) +static int uadk_prov_dh_X9_42_kdf_derive(PROV_DH_KEYEXCH_CTX *pdhctx, unsigned char *secret, + size_t *secretlen, size_t outlen) { - typedef int (*fun_ptr)(void *, const OSSL_PARAM *); - fun_ptr fun = get_default_keymgmt().set_params; + unsigned char *stmp = NULL; + size_t stmplen; + int ret = 0;
- if (!fun) - return 0; - return fun(key, params); + if (secret == NULL) { + *secretlen = pdhctx->kdf_outlen; + return UADK_P_SUCCESS; + } + + if (outlen < pdhctx->kdf_outlen) { + fprintf(stderr, "invalid: outlen(%u) < kdf_outlen(%u)\n", + outlen, pdhctx->kdf_outlen); + return UADK_P_FAIL; + } + + if (!uadk_prov_dh_plain_derive(pdhctx, NULL, &stmplen, 0, 1)) + return UADK_P_FAIL; + + stmp = OPENSSL_secure_malloc(stmplen); + if (stmp == NULL) { + fprintf(stderr, "failed to do OPENSSL_secure_malloc\n"); + return UADK_P_FAIL; + } + + if (uadk_prov_dh_plain_derive(pdhctx, stmp, &stmplen, stmplen, USE_PAD) == UADK_P_FAIL) + goto end; + + /* Do KDF stuff */ + if (pdhctx->kdf_type == PROV_DH_KDF_X9_42_ASN1) { + if (ossl_dh_kdf_X9_42_asn1(secret, pdhctx, stmp, stmplen, NULL) == UADK_P_FAIL) { + fprintf(stderr, "failed to do ossl_dh_kdf_X9_42_asn1\n"); + goto end; + } + } + + *secretlen = pdhctx->kdf_outlen; + ret = UADK_P_SUCCESS; + +end: + OPENSSL_secure_clear_free(stmp, stmplen); + + return ret; }
-static int uadk_dh_keymgmt_validate(const void *keydata, int selection, int checktype) +static int uadk_keyexch_dh_derive(void *dhctx, unsigned char *secret, + size_t *psecretlen, size_t outlen) { - typedef int (*fun_ptr)(const void *, int, int); - fun_ptr fun = get_default_keymgmt().validate; + PROV_DH_KEYEXCH_CTX *pdhctx = (PROV_DH_KEYEXCH_CTX *)dhctx; + int ret = UADK_P_FAIL;
- if (!fun) - return 0; - return fun(keydata, selection, checktype); + if (pdhctx == NULL) { + fprintf(stderr, "invalid: pdhctx is NULL\n"); + return UADK_P_FAIL; + } + + switch (pdhctx->kdf_type) { + case PROV_DH_KDF_NONE: + ret = uadk_prov_dh_plain_derive(pdhctx, secret, psecretlen, outlen, pdhctx->pad); + break; + case PROV_DH_KDF_X9_42_ASN1: + ret = uadk_prov_dh_X9_42_kdf_derive(pdhctx, secret, psecretlen, outlen); + default: + fprintf(stderr, "invalid: unsupport kdf type\n"); + break; + } + + return ret; }
-static void *uadk_dh_keymgmt_gen_init(void *provctx, int selection, - const OSSL_PARAM params[]) +static void *uadk_keyexch_dh_dupctx(void *dhctx) { - typedef void *(*fun_ptr)(void *, int, const OSSL_PARAM *); - fun_ptr fun = get_default_keymgmt().gen_init; + PROV_DH_KEYEXCH_CTX *srcctx = (PROV_DH_KEYEXCH_CTX *)dhctx; + PROV_DH_KEYEXCH_CTX *dstctx;
- if (!fun) + if (srcctx == NULL) { + fprintf(stderr, "invalid: src ctx is NULL\n"); return NULL; - return fun(provctx, selection, params); -} + }
-static int uadk_dh_keymgmt_gen_set_template(void *genctx, void *templ) -{ - typedef int (*fun_ptr)(void *, void *); - fun_ptr fun = get_default_keymgmt().gen_set_template; + dstctx = OPENSSL_zalloc(sizeof(*dstctx)); + if (dstctx == NULL) { + fprintf(stderr, "failed to alloc dst ctx\n"); + return NULL; + }
- if (!fun) - return 0; - return fun(genctx, templ); + memcpy(dstctx, srcctx, sizeof(PROV_DH_KEYEXCH_CTX)); + dstctx->dh = NULL; + dstctx->dhpeer = NULL; + dstctx->kdf_md = NULL; + dstctx->kdf_ukm = NULL; + dstctx->kdf_cekalg = NULL; + + if (srcctx->dh && !DH_up_ref(srcctx->dh)) + goto err; + else + dstctx->dh = srcctx->dh; + + if (srcctx->dhpeer && !DH_up_ref(srcctx->dhpeer)) + goto err; + else + dstctx->dhpeer = srcctx->dhpeer; + + if (srcctx->kdf_md && !EVP_MD_up_ref(srcctx->kdf_md)) + goto err; + else + dstctx->kdf_md = srcctx->kdf_md; + + /* Duplicate UKM data if present */ + if (srcctx->kdf_ukm && srcctx->kdf_ukmlen > 0) { + dstctx->kdf_ukm = OPENSSL_memdup(srcctx->kdf_ukm, + srcctx->kdf_ukmlen); + if (dstctx->kdf_ukm == NULL) + goto err; + } + + if (srcctx->kdf_cekalg != NULL) { + dstctx->kdf_cekalg = OPENSSL_strdup(srcctx->kdf_cekalg); + if (dstctx->kdf_cekalg == NULL) + goto err; + } + + return dstctx; + +err: + uadk_keyexch_dh_freectx(dstctx); + + return NULL; }
-static const -OSSL_PARAM *uadk_dh_keymgmt_gen_settable_params(ossl_unused void *genctx, - ossl_unused void *provctx) +static int uadk_prov_dh_locate_kdf_type(PROV_DH_KEYEXCH_CTX *pdhctx, const OSSL_PARAM params[]) { - typedef const OSSL_PARAM *(*fun_ptr)(void *, void *); - fun_ptr fun = get_default_keymgmt().gen_settable_params; + char name[DH_MAX_PARAM_LEN + 1] = {'\0'}; + const OSSL_PARAM *p; + char *str = NULL;
- if (!fun) - return NULL; - return fun(genctx, provctx); + p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_TYPE); + if (p != NULL) { + str = name; + if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name))) + return UADK_P_FAIL; + + if (name[0] == '\0') + pdhctx->kdf_type = PROV_DH_KDF_NONE; + else if (strcmp(name, OSSL_KDF_NAME_X942KDF_ASN1) == 0) + pdhctx->kdf_type = PROV_DH_KDF_X9_42_ASN1; + else + return UADK_P_FAIL; + } + + return UADK_P_SUCCESS; }
-static int uadk_dh_keymgmt_gen_set_params(void *genctx, +static int uadk_prov_dh_locate_kdf_digest(PROV_DH_KEYEXCH_CTX *pdhctx, const OSSL_PARAM params[]) { - typedef int (*fun_ptr)(void *, const OSSL_PARAM *); - fun_ptr fun = get_default_keymgmt().gen_set_params; + char mdprops[DH_MAX_PARAM_LEN + 1] = {'\0'}; + char name[DH_MAX_PARAM_LEN + 1] = {'\0'}; + const OSSL_PARAM *p; + char *str = NULL;
- if (!fun) - return 0; - return fun(genctx, params); + p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST); + if (p != NULL) { + str = name; + if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name))) + return UADK_P_FAIL; + + str = mdprops; + p = OSSL_PARAM_locate_const(params, + OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS); + if (p != NULL) + if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdprops))) + return UADK_P_FAIL; + + if (pdhctx->kdf_md) + EVP_MD_free(pdhctx->kdf_md); + + pdhctx->kdf_md = EVP_MD_fetch(pdhctx->libctx, name, mdprops); + if (pdhctx->kdf_md == NULL) + return UADK_P_FAIL; + } + + return UADK_P_SUCCESS; }
-static int dh_gencb(int p, int n, BN_GENCB *cb) +static int uadk_prov_dh_locate_kdf_outlen(PROV_DH_KEYEXCH_CTX *pdhctx, + const OSSL_PARAM params[]) { - struct dh_gen_ctx *gctx = BN_GENCB_get_arg(cb); - OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END }; + const OSSL_PARAM *p; + size_t outlen = 0;
- params[0] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_POTENTIAL, &p); - params[1] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_ITERATION, &n); + p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN); + if (p != NULL) { + if (!OSSL_PARAM_get_size_t(p, &outlen)) + return UADK_P_FAIL; + pdhctx->kdf_outlen = outlen; + }
- return gctx->cb(params, gctx->cbarg); + return UADK_P_SUCCESS; }
-static DH *ossl_dh_new_ex(OSSL_LIB_CTX *libctx) +static int uadk_prov_dh_locate_kdf_ukm(PROV_DH_KEYEXCH_CTX *pdhctx, const OSSL_PARAM params[]) { - DH *ret = OPENSSL_zalloc(sizeof(*ret)); + const OSSL_PARAM *p; + void *tmp_ukm = NULL; + size_t tmp_ukmlen;
- if (ret == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE); - return NULL; - } + p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_UKM); + if (p != NULL) { + if (pdhctx->kdf_ukm) + OPENSSL_free(pdhctx->kdf_ukm); + pdhctx->kdf_ukm = NULL; + pdhctx->kdf_ukmlen = 0;
- ret->references = 1; - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { - ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); - OPENSSL_free(ret); - return NULL; + /* ukm is an optional field so it can be NULL */ + if (p->data != NULL && p->data_size != 0) { + if (!OSSL_PARAM_get_octet_string(p, &tmp_ukm, 0, &tmp_ukmlen)) + return UADK_P_FAIL; + pdhctx->kdf_ukm = tmp_ukm; + pdhctx->kdf_ukmlen = tmp_ukmlen; + } }
- ret->libctx = libctx; + return UADK_P_SUCCESS; +}
- return ret; +static int uadk_prov_dh_locate_kdf_pad(PROV_DH_KEYEXCH_CTX *pdhctx, const OSSL_PARAM params[]) +{ + const OSSL_PARAM *p; + unsigned int pad = 0; + + p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_PAD); + if (p != NULL) { + if (!OSSL_PARAM_get_uint(p, &pad)) + return UADK_P_FAIL; + pdhctx->pad = pad ? 1 : 0; + } + + return UADK_P_SUCCESS; }
-static void *uadk_dh_keymgmt_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) +static int uadk_keyexch_dh_set_ctx_params(void *dhctx, const OSSL_PARAM params[]) { - typedef void* (*fun_ptr)(void *, OSSL_CALLBACK *, void *); - struct dh_gen_ctx *gctx = genctx; - DH *dh = NULL; - BN_GENCB *gencb = NULL; - FFC_PARAMS *ffc; - fun_ptr fun; - int ret; + PROV_DH_KEYEXCH_CTX *pdhctx = (PROV_DH_KEYEXCH_CTX *)dhctx; + char name[DH_MAX_PARAM_LEN + 1] = {'\0'}; + int ret = UADK_P_FAIL; + const OSSL_PARAM *p; + char *str = NULL;
- if (gctx == NULL) - return NULL; + if (pdhctx == NULL) { + fprintf(stderr, "invalid: dh ctx is NULL\n"); + return ret; + }
- dh = ossl_dh_new_ex(gctx->libctx); - if (dh == NULL) - return NULL; - ffc = uadk_ossl_dh_get0_params(dh); - if (gctx->ffc_params != NULL - && !ossl_ffc_params_copy(ffc, gctx->ffc_params)) - goto exec_soft; - if (!ossl_ffc_params_set_seed(ffc, gctx->seed, gctx->seedlen)) - goto exec_soft; - gctx->cb = osslcb; - gctx->cbarg = cbarg; - gencb = BN_GENCB_new(); - if (gencb != NULL) - BN_GENCB_set(gencb, dh_gencb, genctx); + /* If params is NULL, no need to set */ + if (params == NULL) + return UADK_P_SUCCESS;
+ pthread_mutex_lock(&dh_mutex); + ret = uadk_prov_dh_locate_kdf_type(pdhctx, params); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to locate kdf type\n"); + goto end; + }
- ret = uadk_dh_generate_key(dh); - if (ret == UADK_DO_SOFT) - goto exec_soft; - uadk_DH_clear_flags(dh, DH_FLAG_TYPE_MASK); - uadk_DH_set_flags(dh, gctx->dh_type); - BN_GENCB_free(gencb); - return dh; + ret = uadk_prov_dh_locate_kdf_digest(pdhctx, params); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to locate kdf digest\n"); + goto end; + }
-exec_soft: - if (dh) - uadk_dh_keymgmt_freedata(dh); - if (gencb) - BN_GENCB_free(gencb); - fun = get_default_keymgmt().gen; - if (!fun) - return NULL; - return fun(genctx, osslcb, cbarg); -} + ret = uadk_prov_dh_locate_kdf_outlen(pdhctx, params); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to locate kdf outlen\n"); + goto end; + }
-static void uadk_dh_keymgmt_gen_cleanup(void *genctx) -{ - typedef void (*fun_ptr)(void *); - fun_ptr fun = get_default_keymgmt().gen_cleanup; + ret = uadk_prov_dh_locate_kdf_ukm(pdhctx, params); + if (ret == UADK_P_FAIL) { + fprintf(stderr, "failed to locate kdf ukm\n"); + goto end; + }
- if (!fun) - return; - fun(genctx); + ret = uadk_prov_dh_locate_kdf_pad(pdhctx, params); + if (ret == UADK_P_FAIL) + fprintf(stderr, "failed to locate kdf pad\n"); + +end: + pthread_mutex_unlock(&dh_mutex); + return ret; }
-static void *uadk_dh_keymgmt_load(const void *reference, size_t reference_sz) +static const OSSL_PARAM known_settable_ctx_params[] = { + OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_PAD, NULL), + OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS, NULL, 0), + OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL), + OSSL_PARAM_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *uadk_keyexch_dh_settable_ctx_params(ossl_unused void *dhctx, + ossl_unused void *provctx) { - typedef void *(*fun_ptr)(const void *, size_t); - fun_ptr fun = get_default_keymgmt().load; + return known_settable_ctx_params; +}
- if (!fun) - return NULL; - return fun(reference, reference_sz); +static const OSSL_PARAM known_gettable_ctx_params[] = { + OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0), + OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL), + OSSL_PARAM_DEFN(OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_PTR, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *uadk_keyexch_dh_gettable_ctx_params(ossl_unused void *dhctx, + ossl_unused void *provctx) +{ + return known_gettable_ctx_params; }
-static void *uadk_dh_keymgmt_dup(const void *keydata_from, int selection) +static int uadk_keyexch_dh_get_ctx_params(void *dhctx, OSSL_PARAM params[]) { - typedef void *(*fun_ptr)(const void *, int); - fun_ptr fun = get_default_keymgmt().dup; + PROV_DH_KEYEXCH_CTX *pdhctx = (PROV_DH_KEYEXCH_CTX *)dhctx; + const char *kdf_type = NULL; + OSSL_PARAM *p;
- if (!fun) - return NULL; - return fun(keydata_from, selection); -} - -const OSSL_DISPATCH uadk_dh_keyexch_functions[] = { - {OSSL_FUNC_KEYEXCH_NEWCTX, - (void (*)(void))uadk_dh_keyexch_newctx}, - {OSSL_FUNC_KEYEXCH_INIT, - (void (*)(void))uadk_dh_keyexch_init}, - {OSSL_FUNC_KEYEXCH_DERIVE, - (void (*)(void))uadk_dh_keyexch_derive}, - {OSSL_FUNC_KEYEXCH_SET_PEER, - (void (*)(void))uadk_dh_keyexch_set_peer}, - {OSSL_FUNC_KEYEXCH_FREECTX, - (void (*)(void))uadk_dh_keyexch_freectx}, - {OSSL_FUNC_KEYEXCH_DUPCTX, - (void (*)(void))uadk_dh_keyexch_dupctx}, - {OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, - (void (*)(void))uadk_dh_keyexch_set_ctx_params}, - {OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS, - (void (*)(void))uadk_dh_keyexch_settable_ctx_params}, - {OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS, - (void (*)(void))uadk_dh_keyexch_get_ctx_params}, - {OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS, - (void (*)(void))uadk_dh_keyexch_gettable_ctx_params}, - {0, NULL} -}; + if (pdhctx == NULL) { + fprintf(stderr, "invalid: dh ctx is NULL\n"); + return UADK_P_FAIL; + }
-const OSSL_DISPATCH uadk_dh_keymgmt_functions[] = { - {OSSL_FUNC_KEYMGMT_NEW, - (void (*)(void))uadk_dh_keymgmt_newdata}, - {OSSL_FUNC_KEYMGMT_GEN_INIT, - (void (*)(void))uadk_dh_keymgmt_gen_init}, - {OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, - (void (*)(void))uadk_dh_keymgmt_gen_set_template}, - {OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, - (void (*)(void))uadk_dh_keymgmt_gen_set_params}, - {OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, - (void (*)(void))uadk_dh_keymgmt_gen_settable_params}, - {OSSL_FUNC_KEYMGMT_GEN, - (void (*)(void))uadk_dh_keymgmt_gen}, - {OSSL_FUNC_KEYMGMT_GEN_CLEANUP, - (void (*)(void))uadk_dh_keymgmt_gen_cleanup}, - {OSSL_FUNC_KEYMGMT_LOAD, - (void (*)(void))uadk_dh_keymgmt_load}, - {OSSL_FUNC_KEYMGMT_FREE, - (void (*)(void))uadk_dh_keymgmt_freedata}, - {OSSL_FUNC_KEYMGMT_GET_PARAMS, - (void (*)(void))uadk_dh_keymgmt_get_params}, - {OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, - (void (*)(void))uadk_dh_keymgmt_gettable_params}, - {OSSL_FUNC_KEYMGMT_SET_PARAMS, - (void (*)(void))uadk_dh_keymgmt_set_params}, - {OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, - (void (*)(void))uadk_dh_keymgmt_settable_params}, - {OSSL_FUNC_KEYMGMT_HAS, - (void (*)(void))uadk_dh_keymgmt_has}, - {OSSL_FUNC_KEYMGMT_MATCH, - (void (*)(void))uadk_dh_keymgmt_match}, - {OSSL_FUNC_KEYMGMT_VALIDATE, - (void (*)(void))uadk_dh_keymgmt_validate}, - {OSSL_FUNC_KEYMGMT_IMPORT, - (void (*)(void))uadk_dh_keymgmt_import}, - {OSSL_FUNC_KEYMGMT_IMPORT_TYPES, - (void (*)(void))uadk_dh_keymgmt_import_types}, - {OSSL_FUNC_KEYMGMT_EXPORT, - (void (*)(void))uadk_dh_keymgmt_export}, - {OSSL_FUNC_KEYMGMT_EXPORT_TYPES, - (void (*)(void))uadk_dh_keymgmt_export_types}, - {OSSL_FUNC_KEYMGMT_DUP, - (void (*)(void))uadk_dh_keymgmt_dup}, - {0, NULL} -}; + p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_TYPE); + if (p != NULL) { + switch (pdhctx->kdf_type) { + case PROV_DH_KDF_NONE: + kdf_type = ""; + break; + case PROV_DH_KDF_X9_42_ASN1: + kdf_type = OSSL_KDF_NAME_X942KDF_ASN1; + break; + default: + fprintf(stderr, "invalid kdf_type\n"); + return UADK_P_FAIL; + }
-void uadk_prov_destroy_dh(void) -{ - pthread_mutex_lock(&dh_mutex); - if (g_dh_res.pid == getpid()) { - wd_dh_uninit2(); - g_dh_res.pid = 0; + if (!OSSL_PARAM_set_utf8_string(p, kdf_type)) { + fprintf(stderr, "failed to set utf8 string for kdf_type\n"); + return UADK_P_FAIL; + } } - pthread_mutex_lock(&dh_mutex); + + p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST); + if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdhctx->kdf_md == NULL + ? "" : EVP_MD_get0_name(pdhctx->kdf_md))) { + fprintf(stderr, "failed to set kdf_md\n"); + return UADK_P_FAIL; + } + + p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN); + if (p != NULL && !OSSL_PARAM_set_size_t(p, pdhctx->kdf_outlen)) { + fprintf(stderr, "failed to set kdf_outlen\n"); + return UADK_P_FAIL; + } + + p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_UKM); + if (p != NULL && !OSSL_PARAM_set_octet_ptr(p, pdhctx->kdf_ukm, pdhctx->kdf_ukmlen)) { + fprintf(stderr, "failed to set kdf_ukm\n"); + return UADK_P_FAIL; + } + + p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_CEK_ALG); + if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdhctx->kdf_cekalg == NULL + ? "" : pdhctx->kdf_cekalg)) { + fprintf(stderr, "failed to set kdf_cekalg\n"); + return UADK_P_FAIL; + } + + return UADK_P_SUCCESS; } diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c index 34027bf..4c2793f 100644 --- a/src/uadk_prov_init.c +++ b/src/uadk_prov_init.c @@ -176,6 +176,7 @@ static void uadk_teardown(void *provctx) uadk_prov_destroy_cipher(); uadk_prov_destroy_rsa(); uadk_prov_sm2_uninit(); + uadk_prov_dh_uninit(); OPENSSL_free(ctx); OSSL_PROVIDER_unload(prov); async_poll_task_free(); diff --git a/src/uadk_prov_pkey.h b/src/uadk_prov_pkey.h index d044597..105d9bb 100644 --- a/src/uadk_prov_pkey.h +++ b/src/uadk_prov_pkey.h @@ -275,6 +275,26 @@ static OSSL_FUNC_signature_get_ctx_md_params_fn uadk_signature_##nm##_get_ctx_md static OSSL_FUNC_signature_gettable_ctx_md_params_fn uadk_signature_##nm##_gettable_ctx_md_params; \ static OSSL_FUNC_signature_set_ctx_md_params_fn uadk_signature_##nm##_set_ctx_md_params; \ static OSSL_FUNC_signature_settable_ctx_md_params_fn uadk_signature_##nm##_settable_ctx_md_params; \ +static UADK_PKEY_SIGNATURE get_default_signature(void) \ +{ \ + static UADK_PKEY_SIGNATURE s_signature; \ + static int initilazed; \ + \ + if (!initilazed) { \ + UADK_PKEY_SIGNATURE *signature = \ + (UADK_PKEY_SIGNATURE *)EVP_SIGNATURE_fetch(NULL, #alg, \ + "provider=default"); \ + \ + if (signature) { \ + s_signature = *signature; \ + EVP_SIGNATURE_free((EVP_SIGNATURE *)signature); \ + initilazed = 1; \ + } else { \ + fprintf(stderr, "failed to EVP_SIGNATURE_fetch default provider\n"); \ + } \ + } \ + return s_signature; \ +} \ const OSSL_DISPATCH uadk_##nm##_signature_functions[] = { \ { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))uadk_signature_##nm##_newctx }, \ { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))uadk_signature_##nm##_sign_init }, \ @@ -347,6 +367,26 @@ static OSSL_FUNC_asym_cipher_get_ctx_params_fn uadk_asym_cipher_##nm##_get_ctx_p static OSSL_FUNC_asym_cipher_gettable_ctx_params_fn uadk_asym_cipher_##nm##_gettable_ctx_params; \ static OSSL_FUNC_asym_cipher_set_ctx_params_fn uadk_asym_cipher_##nm##_set_ctx_params; \ static OSSL_FUNC_asym_cipher_settable_ctx_params_fn uadk_asym_cipher_##nm##_settable_ctx_params; \ +static UADK_PKEY_ASYM_CIPHER get_default_asym_cipher(void) \ +{ \ + static UADK_PKEY_ASYM_CIPHER s_asym_cipher; \ + static int initilazed; \ + \ + if (!initilazed) { \ + UADK_PKEY_ASYM_CIPHER *asym_cipher = \ + (UADK_PKEY_ASYM_CIPHER *)EVP_ASYM_CIPHER_fetch(NULL, #alg, \ + "provider=default"); \ + \ + if (asym_cipher) { \ + s_asym_cipher = *asym_cipher; \ + EVP_ASYM_CIPHER_free((EVP_ASYM_CIPHER *)asym_cipher); \ + initilazed = 1; \ + } else { \ + fprintf(stderr, "failed to EVP_ASYM_CIPHER_fetch default provider\n"); \ + } \ + } \ + return s_asym_cipher; \ +} \ const OSSL_DISPATCH uadk_##nm##_asym_cipher_functions[] = { \ { OSSL_FUNC_ASYM_CIPHER_NEWCTX, (void (*)(void))uadk_asym_cipher_##nm##_newctx }, \ { OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT, \ @@ -368,6 +408,72 @@ const OSSL_DISPATCH uadk_##nm##_asym_cipher_functions[] = { \ { 0, NULL } \ } \
+typedef struct { + int name_id; + char *type_name; + const char *description; + OSSL_PROVIDER *prov; + int refcnt; + + OSSL_FUNC_keyexch_newctx_fn *newctx; + OSSL_FUNC_keyexch_init_fn *init; + OSSL_FUNC_keyexch_set_peer_fn *set_peer; + OSSL_FUNC_keyexch_derive_fn *derive; + OSSL_FUNC_keyexch_freectx_fn *freectx; + OSSL_FUNC_keyexch_dupctx_fn *dupctx; + OSSL_FUNC_keyexch_set_ctx_params_fn *set_ctx_params; + OSSL_FUNC_keyexch_settable_ctx_params_fn *settable_ctx_params; + OSSL_FUNC_keyexch_get_ctx_params_fn *get_ctx_params; + OSSL_FUNC_keyexch_gettable_ctx_params_fn *gettable_ctx_params; +} UADK_PKEY_KEYEXCH; + +#define UADK_PKEY_KEYEXCH_DESCR(nm, alg) \ + static OSSL_FUNC_keyexch_newctx_fn uadk_keyexch_##nm##_newctx; \ + static OSSL_FUNC_keyexch_init_fn uadk_keyexch_##nm##_init; \ + static OSSL_FUNC_keyexch_set_peer_fn uadk_keyexch_##nm##_set_peer; \ + static OSSL_FUNC_keyexch_derive_fn uadk_keyexch_##nm##_derive; \ + static OSSL_FUNC_keyexch_freectx_fn uadk_keyexch_##nm##_freectx; \ + static OSSL_FUNC_keyexch_dupctx_fn uadk_keyexch_##nm##_dupctx; \ + static OSSL_FUNC_keyexch_set_ctx_params_fn uadk_keyexch_##nm##_set_ctx_params; \ + static OSSL_FUNC_keyexch_settable_ctx_params_fn uadk_keyexch_##nm##_settable_ctx_params; \ + static OSSL_FUNC_keyexch_get_ctx_params_fn uadk_keyexch_##nm##_get_ctx_params; \ + static OSSL_FUNC_keyexch_gettable_ctx_params_fn uadk_keyexch_##nm##_gettable_ctx_params; \ +static UADK_PKEY_KEYEXCH get_default_keyexch(void) \ +{ \ + UADK_PKEY_KEYEXCH s_keyexch; \ + static int initilazed; \ + \ + if (!initilazed) { \ + UADK_PKEY_KEYEXCH *keyexch = \ + (UADK_PKEY_KEYEXCH *)EVP_KEYEXCH_fetch(NULL, #alg, "provider=default"); \ + if (keyexch) { \ + s_keyexch = *keyexch; \ + EVP_KEYEXCH_free((EVP_KEYEXCH *)keyexch); \ + initilazed = 1; \ + } else { \ + fprintf(stderr, "failed to EVP_KEYEXCH_fetch default provider\n"); \ + } \ + } \ + return s_keyexch; \ +} \ +const OSSL_DISPATCH uadk_##nm##_keyexch_functions[] = { \ + { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))uadk_keyexch_##nm##_newctx }, \ + { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))uadk_keyexch_##nm##_init }, \ + { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))uadk_keyexch_##nm##_derive }, \ + { OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))uadk_keyexch_##nm##_set_peer }, \ + { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))uadk_keyexch_##nm##_freectx }, \ + { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))uadk_keyexch_##nm##_dupctx }, \ + { OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, \ + (void (*)(void))uadk_keyexch_##nm##_set_ctx_params }, \ + { OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS, \ + (void (*)(void))uadk_keyexch_##nm##_settable_ctx_params }, \ + {OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS, \ + (void (*)(void))uadk_keyexch_##nm##_get_ctx_params }, \ + { OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS, \ + (void (*)(void))uadk_keyexch_##nm##_gettable_ctx_params }, \ + { 0, NULL } \ +} \ + handle_t uadk_prov_ecc_alloc_sess(const EC_KEY *eckey, char *alg); int uadk_prov_ecc_crypto(handle_t sess, struct wd_ecc_req *req, void *usr); int uadk_prov_keymgmt_get_support_state(int alg_tag);
From: Chenghai Huang huangchenghai2@huawei.com
The return value of the execution result is changed to the definition.
Signed-off-by: Chenghai Huang huangchenghai2@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_prov_bio.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/src/uadk_prov_bio.c b/src/uadk_prov_bio.c index 46656c2..661088c 100644 --- a/src/uadk_prov_bio.c +++ b/src/uadk_prov_bio.c @@ -12,6 +12,9 @@ #include <openssl/bio.h> #include "uadk_prov_bio.h"
+#define UADK_PRO_SUCCESS 1 +#define UADK_PRO_FAIL 0 + /* Functions provided by bio */ static OSSL_FUNC_BIO_new_file_fn *c_bio_new_file; static OSSL_FUNC_BIO_new_membuf_fn *c_bio_new_membuf; @@ -72,7 +75,7 @@ int ossl_prov_bio_from_dispatch(const OSSL_DISPATCH *fns) fns++; }
- return 1; + return UADK_PRO_SUCCESS; }
OSSL_CORE_BIO *ossl_prov_bio_new_file(const char *filename, const char *mode) @@ -95,7 +98,7 @@ int ossl_prov_bio_read_ex(OSSL_CORE_BIO *bio, void *data, size_t data_len, size_t *bytes_read) { if (c_bio_read_ex == NULL) - return 0; + return UADK_PRO_FAIL;
return c_bio_read_ex(bio, data, data_len, bytes_read); } @@ -104,7 +107,7 @@ int ossl_prov_bio_write_ex(OSSL_CORE_BIO *bio, const void *data, size_t data_len size_t *written) { if (c_bio_write_ex == NULL) - return 0; + return UADK_PRO_FAIL;
return c_bio_write_ex(bio, data, data_len, written); } @@ -136,7 +139,7 @@ int ossl_prov_bio_ctrl(OSSL_CORE_BIO *bio, int cmd, long num, void *ptr) int ossl_prov_bio_up_ref(OSSL_CORE_BIO *bio) { if (c_bio_up_ref == NULL) - return 0; + return UADK_PRO_FAIL;
return c_bio_up_ref(bio); } @@ -144,7 +147,7 @@ int ossl_prov_bio_up_ref(OSSL_CORE_BIO *bio) int ossl_prov_bio_free(OSSL_CORE_BIO *bio) { if (c_bio_free == NULL) - return 0; + return UADK_PRO_FAIL;
return c_bio_free(bio); } @@ -203,7 +206,7 @@ static int bio_core_new(BIO *bio) { BIO_set_init(bio, 1);
- return 1; + return UADK_PRO_SUCCESS; }
BIO_METHOD *ossl_prov_ctx_get0_core_bio_method(UADK_PROV_CTX *ctx) @@ -219,7 +222,7 @@ static int bio_core_free(BIO *bio) BIO_set_init(bio, 0); ossl_prov_bio_free(BIO_get_data(bio));
- return 1; + return UADK_PRO_SUCCESS; }
BIO_METHOD *ossl_bio_prov_init_bio_method(void)
From: Chenghai Huang huangchenghai2@huawei.com
The length of the input IV and key pointer cannot exceed the maximum length. Otherwise, memory overwriting occurs during the copy.
Signed-off-by: Chenghai Huang huangchenghai2@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_prov_cipher.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c index f6d1581..de3a62a 100644 --- a/src/uadk_prov_cipher.c +++ b/src/uadk_prov_cipher.c @@ -264,6 +264,11 @@ static int uadk_prov_cipher_init(struct cipher_priv_ctx *priv, int cipher_counts = ARRAY_SIZE(cipher_info_table); int i;
+ if (ivlen > IV_LEN || keylen > MAX_KEY_LEN) { + fprintf(stderr, "invalid keylen or ivlen.\n"); + return UADK_E_FAIL; + } + if (iv) memcpy(priv->iv, iv, ivlen);
From: Chenghai Huang huangchenghai2@huawei.com
There is no timeout exit condition in the loop. When busy is returned continuously, an infinite loop occurs.
Signed-off-by: Chenghai Huang huangchenghai2@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_prov_digest.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/src/uadk_prov_digest.c b/src/uadk_prov_digest.c index 776749b..a51ec77 100644 --- a/src/uadk_prov_digest.c +++ b/src/uadk_prov_digest.c @@ -473,6 +473,7 @@ static int uadk_do_digest_async(struct digest_priv_ctx *priv, struct async_op *o { struct uadk_e_cb_info cb_param; int idx, ret; + int cnt = 0;
if (unlikely(priv->switch_flag == UADK_DO_SOFT)) { fprintf(stderr, "async cipher init failed.\n"); @@ -494,15 +495,24 @@ static int uadk_do_digest_async(struct digest_priv_ctx *priv, struct async_op *o ret = wd_do_digest_async(priv->sess, &priv->req); if (ret < 0 && ret != -EBUSY) { fprintf(stderr, "do sec digest async failed.\n"); - async_free_poll_task(op->idx, 0); - return UADK_DIGEST_FAIL; + goto free_poll_task; + } + + if (unlikely(++cnt > ENGINE_SEND_MAX_CNT)) { + fprintf(stderr, "do digest async operation timeout.\n"); + goto free_poll_task; } } while (ret == -EBUSY);
ret = async_pause_job(priv, op, ASYNC_TASK_DIGEST); if (!ret) return UADK_DIGEST_FAIL; + return UADK_DIGEST_SUCCESS; + +free_poll_task: + async_free_poll_task(op->idx, 0); + return UADK_DIGEST_FAIL; }
static int uadk_digest_final(struct digest_priv_ctx *priv, unsigned char *digest)
From: Chenghai Huang huangchenghai2@huawei.com
Deleted unnecessary return values and modified the format.
Use a unified format to define the return values of success and failure.
Signed-off-by: Chenghai Huang huangchenghai2@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_digest.c | 9 +- src/uadk_prov_bio.c | 4 +- src/uadk_prov_bio.h | 2 +- src/uadk_prov_cipher.c | 253 ++++++++++++++++++++--------------------- src/uadk_prov_digest.c | 2 +- src/uadk_prov_init.c | 4 +- 6 files changed, 131 insertions(+), 143 deletions(-)
diff --git a/src/uadk_digest.c b/src/uadk_digest.c index 073c171..e6a7605 100644 --- a/src/uadk_digest.c +++ b/src/uadk_digest.c @@ -281,7 +281,7 @@ static uint32_t sec_digest_get_sw_threshold(int n_id) return digest_pkt_threshold_table[i].threshold; } while (++i < threshold_table_size);
- fprintf(stderr, "nid %d not found in digest threshold table", n_id); + fprintf(stderr, "nid %d not found in digest threshold table.\n", n_id); return 0; }
@@ -384,8 +384,8 @@ static __u32 sched_single_pick_next_ctx(handle_t sched_ctx, { if (sched_mode) return CTX_ASYNC; - else - return CTX_SYNC; + + return CTX_SYNC; }
static int sched_single_poll_policy(handle_t h_sched_ctx, @@ -962,8 +962,7 @@ static int uadk_e_digest_cleanup(EVP_MD_CTX *ctx) priv->sess = 0; }
- if (priv->soft_ctx) - digest_soft_cleanup(priv); + digest_soft_cleanup(priv);
return 1; } diff --git a/src/uadk_prov_bio.c b/src/uadk_prov_bio.c index 661088c..5be3e8a 100644 --- a/src/uadk_prov_bio.c +++ b/src/uadk_prov_bio.c @@ -27,7 +27,7 @@ static OSSL_FUNC_BIO_up_ref_fn *c_bio_up_ref; static OSSL_FUNC_BIO_free_fn *c_bio_free; static OSSL_FUNC_BIO_vprintf_fn *c_bio_vprintf;
-int ossl_prov_bio_from_dispatch(const OSSL_DISPATCH *fns) +void ossl_prov_bio_from_dispatch(const OSSL_DISPATCH *fns) { while (fns && fns->function_id != 0) { switch (fns->function_id) { @@ -74,8 +74,6 @@ int ossl_prov_bio_from_dispatch(const OSSL_DISPATCH *fns) } fns++; } - - return UADK_PRO_SUCCESS; }
OSSL_CORE_BIO *ossl_prov_bio_new_file(const char *filename, const char *mode) diff --git a/src/uadk_prov_bio.h b/src/uadk_prov_bio.h index 2b0d044..e7bb1aa 100644 --- a/src/uadk_prov_bio.h +++ b/src/uadk_prov_bio.h @@ -13,7 +13,7 @@ #include <openssl/core.h> #include "uadk_prov.h"
-int ossl_prov_bio_from_dispatch(const OSSL_DISPATCH *fns); +void ossl_prov_bio_from_dispatch(const OSSL_DISPATCH *fns);
OSSL_CORE_BIO *ossl_prov_bio_new_file(const char *filename, const char *mode); OSSL_CORE_BIO *ossl_prov_bio_new_membuf(const char *filename, int len); diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c index de3a62a..7188954 100644 --- a/src/uadk_prov_cipher.c +++ b/src/uadk_prov_cipher.c @@ -42,15 +42,18 @@ #define IV_LEN 16 #define ENV_ENABLED 1 #define MAX_KEY_LEN 64 -#define ALG_NAME_SIZE 128 +#define ALG_NAME_SIZE 128 #define GENERIC_BLOCK_SIZE 16
+#define UADK_E_SUCCESS 1 +#define UADK_E_FAIL 0 + /* Internal flags that can be queried */ -#define PROV_CIPHER_FLAG_AEAD 0x0001 -#define PROV_CIPHER_FLAG_CUSTOM_IV 0x0002 -#define PROV_CIPHER_FLAG_CTS 0x0004 -#define PROV_CIPHER_FLAG_TLS1_MULTIBLOCK 0x0008 -#define PROV_CIPHER_FLAG_RAND_KEY 0x0010 +#define PROV_CIPHER_FLAG_AEAD 0x0001 +#define PROV_CIPHER_FLAG_CUSTOM_IV 0x0002 +#define PROV_CIPHER_FLAG_CTS 0x0004 +#define PROV_CIPHER_FLAG_TLS1_MULTIBLOCK 0x0008 +#define PROV_CIPHER_FLAG_RAND_KEY 0x0010
/* Internal flags that are only used within the provider */ #define PROV_CIPHER_FLAG_VARIABLE_LENGTH 0x0100 @@ -124,7 +127,7 @@ static struct cipher_info cipher_info_table[] = { static int uadk_fetch_sw_cipher(struct cipher_priv_ctx *priv) { if (priv->sw_cipher) - return 1; + return UADK_E_SUCCESS;
switch (priv->nid) { case NID_aes_128_cbc: @@ -198,9 +201,9 @@ static int uadk_fetch_sw_cipher(struct cipher_priv_ctx *priv) }
if (unlikely(priv->sw_cipher == NULL)) - return 0; + return UADK_E_FAIL;
- return 1; + return UADK_E_SUCCESS; }
static int uadk_prov_cipher_sw_init(struct cipher_priv_ctx *priv, @@ -208,33 +211,33 @@ static int uadk_prov_cipher_sw_init(struct cipher_priv_ctx *priv, const unsigned char *iv) { if (!uadk_fetch_sw_cipher(priv)) - return 0; + return UADK_E_FAIL;
if (!EVP_CipherInit_ex2(priv->sw_ctx, priv->sw_cipher, key, iv, priv->enc, NULL)) { fprintf(stderr, "SW cipher init error!\n"); - return 0; + return UADK_E_FAIL; }
priv->switch_threshold = SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT;
- return 1; + return UADK_E_SUCCESS; }
static int uadk_prov_cipher_soft_work(struct cipher_priv_ctx *priv, unsigned char *out, int *outl, const unsigned char *in, size_t len) { if (priv->sw_cipher == NULL) - return 0; + return UADK_E_FAIL;
if (!EVP_CipherUpdate(priv->sw_ctx, out, outl, in, len)) { fprintf(stderr, "EVP_CipherUpdate sw_ctx failed.\n"); - return 0; + return UADK_E_FAIL; }
priv->switch_flag = UADK_DO_SOFT;
- return 1; + return UADK_E_SUCCESS; }
static int uadk_cipher_env_poll(void *ctx) @@ -283,7 +286,7 @@ static int uadk_prov_cipher_init(struct cipher_priv_ctx *priv,
if (i == cipher_counts) { fprintf(stderr, "failed to setup the private ctx.\n"); - return 0; + return UADK_E_FAIL; }
if (key) @@ -292,7 +295,7 @@ static int uadk_prov_cipher_init(struct cipher_priv_ctx *priv, if (enable_sw_offload) uadk_prov_cipher_sw_init(priv, key, iv);
- return 1; + return UADK_E_SUCCESS; }
static void async_cb(struct wd_cipher_req *req, void *data) @@ -324,7 +327,7 @@ static void ctr_iv_inc(uint8_t *counter, __u32 c)
/* * Since the counter has been increased 1 by the hardware, - * so the c need to decrease 1. + * so the c need to decrease 1. */ c_value -= 1; do { @@ -372,8 +375,9 @@ static int uadk_do_cipher_sync(struct cipher_priv_ctx *priv)
ret = wd_do_cipher_sync(priv->sess, &priv->req); if (ret) - return 0; - return 1; + return UADK_E_FAIL; + + return UADK_E_SUCCESS; }
static int uadk_do_cipher_async(struct cipher_priv_ctx *priv, struct async_op *op) @@ -383,7 +387,7 @@ static int uadk_do_cipher_async(struct cipher_priv_ctx *priv, struct async_op *o
if (unlikely(priv->switch_flag == UADK_DO_SOFT)) { fprintf(stderr, "async cipher init failed.\n"); - return 0; + return UADK_E_FAIL; }
cb_param.op = op; @@ -392,7 +396,7 @@ static int uadk_do_cipher_async(struct cipher_priv_ctx *priv, struct async_op *o priv->req.cb_param = &cb_param; ret = async_get_free_task(&idx); if (!ret) - return 0; + return UADK_E_FAIL;
op->idx = idx; do { @@ -400,17 +404,18 @@ static int uadk_do_cipher_async(struct cipher_priv_ctx *priv, struct async_op *o if (ret < 0 && ret != -EBUSY) { fprintf(stderr, "do sec cipher failed, switch to soft cipher.\n"); async_free_poll_task(op->idx, 0); - return 0; + return UADK_E_FAIL; } } while (ret == -EBUSY);
ret = async_pause_job(priv, op, ASYNC_TASK_CIPHER); if (!ret) - return 0; - return 1; + return UADK_E_FAIL; + + return UADK_E_SUCCESS; }
-static void uadk_prov_cipher_ctx_init(struct cipher_priv_ctx *priv) +static int uadk_prov_cipher_ctx_init(struct cipher_priv_ctx *priv) { struct sched_params params = {0}; int ret; @@ -469,8 +474,10 @@ static void uadk_prov_cipher_ctx_init(struct cipher_priv_ctx *priv)
if (!priv->sess) { priv->sess = wd_cipher_alloc_sess(&priv->setup); - if (!priv->sess) + if (!priv->sess) { fprintf(stderr, "uadk failed to alloc session!\n"); + return UADK_E_FAIL; + } }
ret = wd_cipher_set_key(priv->sess, priv->key, priv->keylen); @@ -478,7 +485,10 @@ static void uadk_prov_cipher_ctx_init(struct cipher_priv_ctx *priv) wd_cipher_free_sess(priv->sess); priv->sess = 0; fprintf(stderr, "uadk failed to set key!\n"); + return UADK_E_FAIL; } + + return UADK_E_SUCCESS; }
/* @@ -522,29 +532,29 @@ static size_t ossl_cipher_fillblock(unsigned char *buf, size_t *buflen, * Fills the buffer with trailing data from an encryption/decryption that didn't * fit into a full block. */ -int ossl_cipher_trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize, +static int ossl_cipher_trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize, const unsigned char **in, size_t *inlen) { if (*inlen == 0) - return 1; + return UADK_E_SUCCESS;
if (*buflen + *inlen > blocksize) { ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); - return 0; + return UADK_E_FAIL; }
memcpy(buf + *buflen, *in, *inlen); *buflen += *inlen; *inlen = 0;
- return 1; + return UADK_E_SUCCESS; }
/* Pad the final block for encryption */ static void ossl_cipher_padblock(unsigned char *buf, size_t *buflen, size_t blocksize) { - size_t i; unsigned char pad = (unsigned char)(blocksize - *buflen); + size_t i;
for (i = *buflen; i < blocksize; i++) buf[i] = pad; @@ -552,12 +562,12 @@ static void ossl_cipher_padblock(unsigned char *buf, size_t *buflen, size_t bloc
static int ossl_cipher_unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize) { - size_t pad, i; size_t len = *buflen; + size_t pad, i;
if (len != blocksize) { ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); - return 0; + return UADK_E_FAIL; }
/* @@ -567,16 +577,16 @@ static int ossl_cipher_unpadblock(unsigned char *buf, size_t *buflen, size_t blo pad = buf[blocksize - 1]; if (pad == 0 || pad > blocksize) { ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT); - return 0; + return UADK_E_FAIL; } for (i = 0; i < pad; i++) { if (buf[--len] != pad) { ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT); - return 0; + return UADK_E_FAIL; } } *buflen = len; - return 1; + return UADK_E_SUCCESS; }
static int uadk_prov_hw_cipher(struct cipher_priv_ctx *priv, unsigned char *out, @@ -589,7 +599,7 @@ static int uadk_prov_hw_cipher(struct cipher_priv_ctx *priv, unsigned char *out,
if (outsize < blksz) { ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); - return 0; + return UADK_E_FAIL; }
priv->switch_flag = UADK_DO_HW; @@ -598,38 +608,34 @@ static int uadk_prov_hw_cipher(struct cipher_priv_ctx *priv, unsigned char *out, priv->req.dst = out; priv->req.out_buf_bytes = inlen;
- uadk_prov_cipher_ctx_init(priv); + ret = uadk_prov_cipher_ctx_init(priv); + if (ret != UADK_E_SUCCESS) + return ret; + + ret = async_setup_async_event_notification(&op); + if (!ret) { + fprintf(stderr, "failed to setup async event notification.\n"); + return UADK_E_FAIL; + }
- if (inlen <= blksz) { - /* small packet directly using sync? */ + if (op.job == NULL) { + /* Synchronous, only the synchronous mode supports soft computing */ ret = uadk_do_cipher_sync(priv); - if (!ret) - return 0; - } else { - ret = async_setup_async_event_notification(&op); if (!ret) { - fprintf(stderr, "failed to setup async event notification.\n"); - return 0; + async_clear_async_event_notification(); + return UADK_E_FAIL; } - - if (op.job == NULL) { - /* Synchronous, only the synchronous mode supports soft computing */ - ret = uadk_do_cipher_sync(priv); - if (!ret) { - async_clear_async_event_notification(); - return 0; - } - } else { - ret = uadk_do_cipher_async(priv, &op); - if (!ret) { - async_clear_async_event_notification(); - return 0; - } + } else { + ret = uadk_do_cipher_async(priv, &op); + if (!ret) { + async_clear_async_event_notification(); + return UADK_E_FAIL; } }
uadk_cipher_update_priv_ctx(priv); - return 1; + + return UADK_E_SUCCESS; }
static int uadk_prov_do_cipher(struct cipher_priv_ctx *priv, unsigned char *out, @@ -661,7 +667,7 @@ static int uadk_prov_do_cipher(struct cipher_priv_ctx *priv, unsigned char *out, */ if (priv->bufsz == blksz && (priv->enc || inlen > 0 || !priv->pad)) { ret = uadk_prov_hw_cipher(priv, out, outl, outsize, priv->buf, blksz); - if (ret != 1) { + if (ret != UADK_E_SUCCESS) { fprintf(stderr, "do hw ciphers failed.\n"); if (priv->sw_cipher) goto do_soft; @@ -681,7 +687,7 @@ static int uadk_prov_do_cipher(struct cipher_priv_ctx *priv, unsigned char *out,
if (nextblocks > 0) { ret = uadk_prov_hw_cipher(priv, out, outl, outsize, in, nextblocks); - if (ret != 1) { + if (ret != UADK_E_SUCCESS) { fprintf(stderr, "do hw ciphers failed.\n"); if (priv->sw_cipher) goto do_soft; @@ -695,7 +701,7 @@ static int uadk_prov_do_cipher(struct cipher_priv_ctx *priv, unsigned char *out, if (inlen != 0 && !ossl_cipher_trailingdata(priv->buf, &priv->bufsz, blksz, &in, &inlen)) - return 0; + return UADK_E_FAIL;
*outl = outlint; return inlen == 0; @@ -710,11 +716,11 @@ do_soft: ret = uadk_prov_cipher_soft_work(priv, out, &outlint, in, inlen); if (ret) { *outl = outlint; - return 1; + return UADK_E_SUCCESS; }
fprintf(stderr, "do soft ciphers failed.\n"); - return 0; + return UADK_E_FAIL; }
void uadk_prov_destroy_cipher(void) @@ -747,20 +753,21 @@ static int uadk_prov_cipher_cipher(void *vctx, unsigned char *out, size_t *outl,
if (inl == 0) { *outl = 0; - return 1; + return UADK_E_SUCCESS; }
if (outsize < inl) { ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); - return 0; + return UADK_E_FAIL; }
ret = uadk_prov_do_cipher(priv, out, outl, outsize, in, inl); - if (ret != 1) + if (ret != UADK_E_SUCCESS) return ret;
*outl = inl; - return 1; + + return UADK_E_SUCCESS; }
static int uadk_prov_cipher_block_final(void *vctx, unsigned char *out, @@ -784,36 +791,36 @@ static int uadk_prov_cipher_block_final(void *vctx, unsigned char *out, ossl_cipher_padblock(priv->buf, &priv->bufsz, blksz); } else if (priv->bufsz == 0) { *outl = 0; - return 1; + return UADK_E_SUCCESS; } else if (priv->bufsz != blksz) { ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH); - return 0; + return UADK_E_FAIL; }
if (outsize < blksz) { ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); - return 0; + return UADK_E_FAIL; }
ret = uadk_prov_hw_cipher(priv, out, outl, outsize, priv->buf, blksz); - if (ret != 1) { + if (ret != UADK_E_SUCCESS) { fprintf(stderr, "do hw ciphers failed.\n"); if (priv->sw_cipher) goto do_soft; return ret; } *outl = blksz; - return 1; + return UADK_E_SUCCESS; }
/* dec should handle last blk since pad */ if (priv->bufsz != blksz) { if (priv->bufsz == 0 && !priv->pad) { *outl = 0; - return 1; + return UADK_E_SUCCESS; } ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH); - return 0; + return UADK_E_FAIL; }
ret = uadk_prov_hw_cipher(priv, priv->buf, outl, outsize, priv->buf, blksz); @@ -826,27 +833,27 @@ static int uadk_prov_cipher_block_final(void *vctx, unsigned char *out,
if (priv->pad && !ossl_cipher_unpadblock(priv->buf, &priv->bufsz, blksz)) { /* ERR_raise already called */ - return 0; + return UADK_E_FAIL; }
if (outsize < priv->bufsz) { ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); - return 0; + return UADK_E_FAIL; }
memcpy(out, priv->buf, priv->bufsz); *outl = priv->bufsz; priv->bufsz = 0;
- return 1; + return UADK_E_SUCCESS;
do_soft: if (!EVP_CipherFinal_ex(priv->sw_ctx, out, &sw_final_len)) { fprintf(stderr, "EVP_CipherFinal_ex sw_ctx failed.\n"); - return 0; + return UADK_E_FAIL; } *outl = sw_final_len; - return 1; + return UADK_E_SUCCESS; }
static int uadk_prov_cipher_block_update(void *vctx, unsigned char *out, @@ -854,26 +861,21 @@ static int uadk_prov_cipher_block_update(void *vctx, unsigned char *out, const unsigned char *in, size_t inl) { struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; - int ret;
if (!vctx || !in || !out || !outl) return UADK_E_FAIL;
if (inl == 0) { *outl = 0; - return 1; + return UADK_E_SUCCESS; }
if (outsize < inl) { ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); - return 0; + return UADK_E_FAIL; }
- ret = uadk_prov_do_cipher(priv, out, outl, outsize, in, inl); - if (ret != 1) - return ret; - - return 1; + return uadk_prov_do_cipher(priv, out, outl, outsize, in, inl); }
static int uadk_prov_cipher_stream_update(void *vctx, unsigned char *out, @@ -881,6 +883,7 @@ static int uadk_prov_cipher_stream_update(void *vctx, unsigned char *out, const unsigned char *in, size_t inl) { struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; + int len = 0; int ret;
if (!vctx || !in || !out || !outl) @@ -888,12 +891,12 @@ static int uadk_prov_cipher_stream_update(void *vctx, unsigned char *out,
if (inl == 0) { *outl = 0; - return 1; + return UADK_E_SUCCESS; }
if (outsize < inl) { ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); - return 0; + return UADK_E_FAIL; }
if (priv->sw_cipher && @@ -904,27 +907,25 @@ static int uadk_prov_cipher_stream_update(void *vctx, unsigned char *out, }
ret = uadk_prov_hw_cipher(priv, out, outl, outsize, in, inl); - if (ret != 1) { + if (ret != UADK_E_SUCCESS) { if (priv->sw_cipher) goto do_soft; return ret; }
*outl = inl; - return 1; + return UADK_E_SUCCESS;
do_soft: - int len = 0; - /* have isseu if both using hw and soft partly */ ret = uadk_prov_cipher_soft_work(priv, out, &len, in, inl); if (ret) { *outl = len; - return 1; + return UADK_E_SUCCESS; }
fprintf(stderr, "do soft ciphers failed.\n"); - return 0; + return UADK_E_FAIL; }
static int uadk_prov_cipher_stream_final(void *vctx, unsigned char *out, @@ -940,14 +941,14 @@ static int uadk_prov_cipher_stream_final(void *vctx, unsigned char *out, priv->switch_flag == UADK_DO_SOFT) { if (!EVP_CipherFinal_ex(priv->sw_ctx, out, &sw_final_len)) { fprintf(stderr, "EVP_CipherFinal_ex sw_ctx failed.\n"); - return 0; + return UADK_E_FAIL; } *outl = sw_final_len; - return 1; + return UADK_E_SUCCESS; }
*outl = 0; - return 1; + return UADK_E_SUCCESS; }
static int uadk_prov_cipher_einit(void *vctx, const unsigned char *key, size_t keylen, @@ -955,7 +956,6 @@ static int uadk_prov_cipher_einit(void *vctx, const unsigned char *key, size_t k const OSSL_PARAM params[]) { struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; - int ret;
if (!vctx) return UADK_E_FAIL; @@ -963,11 +963,7 @@ static int uadk_prov_cipher_einit(void *vctx, const unsigned char *key, size_t k priv->req.op_type = WD_CIPHER_ENCRYPTION; priv->enc = 1;
- ret = uadk_prov_cipher_init(priv, key, keylen, iv, ivlen); - if (unlikely(ret != 1)) - return 0; - - return 1; + return uadk_prov_cipher_init(priv, key, keylen, iv, ivlen); }
static int uadk_prov_cipher_dinit(void *vctx, const unsigned char *key, size_t keylen, @@ -975,7 +971,6 @@ static int uadk_prov_cipher_dinit(void *vctx, const unsigned char *key, size_t k const OSSL_PARAM params[]) { struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; - int ret;
if (!vctx) return UADK_E_FAIL; @@ -983,11 +978,7 @@ static int uadk_prov_cipher_dinit(void *vctx, const unsigned char *key, size_t k priv->req.op_type = WD_CIPHER_DECRYPTION; priv->enc = 0;
- ret = uadk_prov_cipher_init(priv, key, keylen, iv, ivlen); - if (unlikely(ret != 1)) - return 0; - - return 1; + return uadk_prov_cipher_init(priv, key, keylen, iv, ivlen); }
static const OSSL_PARAM uadk_prov_settable_ctx_params[] = { @@ -1016,7 +1007,7 @@ static int uadk_prov_cipher_set_ctx_params(void *vctx, const OSSL_PARAM params[]
if (!OSSL_PARAM_get_uint(p, &pad)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); - return 0; + return UADK_E_FAIL; } priv->pad = pad ? 1 : 0; EVP_CIPHER_CTX_set_padding(priv->sw_ctx, pad); @@ -1028,11 +1019,11 @@ static int uadk_prov_cipher_set_ctx_params(void *vctx, const OSSL_PARAM params[]
if (!OSSL_PARAM_get_size_t(p, &keylen)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); - return 0; + return UADK_E_FAIL; } if (priv->keylen != keylen) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); - return 0; + return UADK_E_FAIL; } }
@@ -1050,31 +1041,31 @@ static int uadk_prov_cipher_get_ctx_params(void *vctx, OSSL_PARAM params[]) p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, priv->keylen)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; + return UADK_E_FAIL; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, priv->ivlen)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; + return UADK_E_FAIL; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_PADDING); if (p != NULL && !OSSL_PARAM_set_uint(p, priv->pad)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; + return UADK_E_FAIL; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV); if (p != NULL && !OSSL_PARAM_set_octet_string(p, priv->iv, priv->ivlen) && !OSSL_PARAM_set_octet_ptr(p, &priv->iv, priv->ivlen)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; + return UADK_E_FAIL; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV); if (p != NULL && !OSSL_PARAM_set_octet_string(p, priv->iv, priv->ivlen) && !OSSL_PARAM_set_octet_ptr(p, &priv->iv, priv->ivlen)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; + return UADK_E_FAIL; } - return 1; + return UADK_E_SUCCESS; }
static const OSSL_PARAM uadk_prov_default_ctx_params[] = { @@ -1117,29 +1108,29 @@ static int ossl_cipher_generic_get_params(OSSL_PARAM params[], unsigned int md, p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE); if (p != NULL && !OSSL_PARAM_set_uint(p, md)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; + return UADK_E_FAIL; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CUSTOM_IV); if (p != NULL && !OSSL_PARAM_set_int(p, (flags & PROV_CIPHER_FLAG_CUSTOM_IV) != 0)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; + return UADK_E_FAIL; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, kbits)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; + return UADK_E_FAIL; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE); if (p != NULL && !OSSL_PARAM_set_size_t(p, blkbits)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; + return UADK_E_FAIL; } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ivbits)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; + return UADK_E_FAIL; } - return 1; + return UADK_E_SUCCESS; }
static void uadk_prov_cipher_freectx(void *ctx) @@ -1176,8 +1167,8 @@ static void *uadk_##nm##_newctx(void *provctx) \ if (ctx->sw_ctx == NULL) \ fprintf(stderr, "EVP_CIPHER_CTX_new failed.\n"); \ strncpy(ctx->alg_name, #algnm, ALG_NAME_SIZE - 1); \ - if (strcmp(#typ, "block") == 0) \ - ctx->pad = 1;\ + if (strcmp(#typ, "block") == 0) \ + ctx->pad = 1; \ return ctx; \ } \ static OSSL_FUNC_cipher_get_params_fn uadk_##nm##_get_params; \ diff --git a/src/uadk_prov_digest.c b/src/uadk_prov_digest.c index a51ec77..bc135cd 100644 --- a/src/uadk_prov_digest.c +++ b/src/uadk_prov_digest.c @@ -322,7 +322,7 @@ soft_init:
static void uadk_fill_mac_buffer_len(struct digest_priv_ctx *priv) { - /* Sha224 and Sha384 need full length mac buffer as doing long hash */ + /* Sha224 and Sha384 and Sha512-XXX need full length mac buffer as doing long hash */ switch (priv->e_nid) { case NID_sha224: priv->req.out_bytes = (priv->req.has_next == DIGEST_DOING) ? diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c index 4c2793f..52a5da0 100644 --- a/src/uadk_prov_init.c +++ b/src/uadk_prov_init.c @@ -225,7 +225,7 @@ static int uadk_prov_ctx_set_core_bio_method(struct uadk_prov_ctx *ctx)
core_bio = ossl_bio_prov_init_bio_method(); if (core_bio == NULL) { - fprintf(stderr, "failed to set bio from dispatch\n"); + fprintf(stderr, "failed to set bio from dispatch\n"); return 0; }
@@ -268,7 +268,7 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, return 0; }
- (void)ossl_prov_bio_from_dispatch(oin); + ossl_prov_bio_from_dispatch(oin); ossl_prov_core_from_dispatch(oin);
/* get parameters from uadk_provider.cnf */
From: Chenghai Huang huangchenghai2@huawei.com
The following 17 AES algorithms are added: AES-128-CBC AES-192-CBC AES-256-CBC AES-128-ECB AES-192-ECB AES-256-ECB AES-128-XTS AES-256-XTS AES-128-CTR AES-192-CTR AES-256-CTR AES-128-OFB AES-192-OFB AES-256-OFB AES-128-CFB AES-192-CFB AES-256-CFB
Signed-off-by: Chenghai Huang huangchenghai2@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_prov.h | 33 ++++++++++++++++++++++----------- src/uadk_prov_init.c | 26 +++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 12 deletions(-)
diff --git a/src/uadk_prov.h b/src/uadk_prov.h index 1b4816e..3655437 100644 --- a/src/uadk_prov.h +++ b/src/uadk_prov.h @@ -128,17 +128,28 @@ extern const OSSL_DISPATCH uadk_sha512_functions[FUNC_MAX_NUM]; extern const OSSL_DISPATCH uadk_sha512_224_functions[FUNC_MAX_NUM]; extern const OSSL_DISPATCH uadk_sha512_256_functions[FUNC_MAX_NUM];
- -extern const OSSL_DISPATCH uadk_aes_128_cbc_functions[]; -extern const OSSL_DISPATCH uadk_aes_192_cbc_functions[]; -extern const OSSL_DISPATCH uadk_aes_256_cbc_functions[]; -extern const OSSL_DISPATCH uadk_aes_128_ecb_functions[]; -extern const OSSL_DISPATCH uadk_aes_192_ecb_functions[]; -extern const OSSL_DISPATCH uadk_aes_256_ecb_functions[]; -extern const OSSL_DISPATCH uadk_aes_128_xts_functions[]; -extern const OSSL_DISPATCH uadk_aes_256_xts_functions[]; -extern const OSSL_DISPATCH uadk_sm4_cbc_functions[]; -extern const OSSL_DISPATCH uadk_sm4_ecb_functions[]; +extern const OSSL_DISPATCH uadk_aes_128_cbc_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_aes_192_cbc_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_aes_256_cbc_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_aes_128_ecb_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_aes_192_ecb_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_aes_256_ecb_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_aes_128_xts_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_aes_256_xts_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_aes_128_ctr_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_aes_192_ctr_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_aes_256_ctr_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_aes_128_ofb128_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_aes_192_ofb128_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_aes_256_ofb128_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_aes_128_cfb128_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_aes_192_cfb128_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_aes_256_cfb128_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_sm4_cbc_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_sm4_ecb_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_sm4_ofb128_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_sm4_cfb128_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_sm4_ctr_functions[FUNC_MAX_NUM]; extern const OSSL_DISPATCH uadk_des_ede3_cbc_functions[]; extern const OSSL_DISPATCH uadk_des_ede3_ecb_functions[];
diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c index 52a5da0..05a1b9f 100644 --- a/src/uadk_prov_init.c +++ b/src/uadk_prov_init.c @@ -89,10 +89,34 @@ const OSSL_ALGORITHM uadk_prov_ciphers[] = { uadk_aes_128_xts_functions, "uadk_provider aes-128-xts" }, { "AES-256-XTS", UADK_DEFAULT_PROPERTIES, uadk_aes_256_xts_functions, "uadk_provider aes-256-xts" }, - { "SM4-CBC:SM4", UADK_DEFAULT_PROPERTIES, + { "AES-128-CTR", UADK_DEFAULT_PROPERTIES, + uadk_aes_128_ctr_functions, "uadk_provider aes-128-ctr" }, + { "AES-192-CTR", UADK_DEFAULT_PROPERTIES, + uadk_aes_192_ctr_functions, "uadk_provider aes-192-ctr" }, + { "AES-256-CTR", UADK_DEFAULT_PROPERTIES, + uadk_aes_256_ctr_functions, "uadk_provider aes-256-ctr" }, + { "AES-128-OFB", UADK_DEFAULT_PROPERTIES, + uadk_aes_128_ofb128_functions, "uadk_provider aes-128-ofb" }, + { "AES-192-OFB", UADK_DEFAULT_PROPERTIES, + uadk_aes_192_ofb128_functions, "uadk_provider aes-192-ofb" }, + { "AES-256-OFB", UADK_DEFAULT_PROPERTIES, + uadk_aes_256_ofb128_functions, "uadk_provider aes-256-ofb" }, + { "AES-128-CFB", UADK_DEFAULT_PROPERTIES, + uadk_aes_128_cfb128_functions, "uadk_provider aes-128-cfb" }, + { "AES-192-CFB", UADK_DEFAULT_PROPERTIES, + uadk_aes_192_cfb128_functions, "uadk_provider aes-192-cfb" }, + { "AES-256-CFB", UADK_DEFAULT_PROPERTIES, + uadk_aes_256_cfb128_functions, "uadk_provider aes-256-cfb" }, + { "SM4-CBC", UADK_DEFAULT_PROPERTIES, uadk_sm4_cbc_functions, "uadk_provider sm4-cbc" }, { "SM4-ECB", UADK_DEFAULT_PROPERTIES, uadk_sm4_ecb_functions, "uadk_provider sm4-ecb" }, + { "SM4-OFB", UADK_DEFAULT_PROPERTIES, + uadk_sm4_ofb128_functions, "uadk_provider sm4-ofb" }, + { "SM4-CFB", UADK_DEFAULT_PROPERTIES, + uadk_sm4_cfb128_functions, "uadk_provider sm4-cfb" }, + { "SM4-CTR", UADK_DEFAULT_PROPERTIES, + uadk_sm4_ctr_functions, "uadk_provider sm4-ctr" }, { "DES-EDE3-CBC", UADK_DEFAULT_PROPERTIES, uadk_des_ede3_cbc_functions, "uadk_provider des-ede3-cbc" }, { "DES-EDE3-ECB", UADK_DEFAULT_PROPERTIES,
From: Chenghai Huang huangchenghai2@huawei.com
In the update operation, the first packet needs to combine the previous unprocessed data into a 512 KB packet for calculation.
Other data is calculated based on the maximum packet length (16M-512B) of the UADK
In this way, a computing resource required for copying may be omitted, and a data volume of once hardware computation may be increased, thereby reducing a quantity of times of sending and receiving data, and better exerting hardware acceleration performance.
Signed-off-by: Chenghai Huang huangchenghai2@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_digest.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/src/uadk_digest.c b/src/uadk_digest.c index e6a7605..ed68ee2 100644 --- a/src/uadk_digest.c +++ b/src/uadk_digest.c @@ -684,14 +684,19 @@ static int digest_update_inner(EVP_MD_CTX *ctx, const void *data, size_t data_le digest_set_msg_state(priv, false);
do { - if (left_len == data_len) { + /* + * If there is data in the buffer, it will be filled and processed. Otherwise, it + * will be processed according to the UADK package len(16M-512Byte). Finally the + * remaining data less than the size of the buffer will be stored in the buffer. + */ + if (priv->last_update_bufflen != 0) { processing_len = DIGEST_BLOCK_SIZE - priv->last_update_bufflen; uadk_memcpy(priv->data + priv->last_update_bufflen, tmpdata, processing_len);
- priv->last_update_bufflen = DIGEST_BLOCK_SIZE; priv->req.in_bytes = DIGEST_BLOCK_SIZE; priv->req.in = priv->data; + priv->last_update_bufflen = 0; } else { if (left_len > BUF_LEN) processing_len = BUF_LEN; @@ -723,14 +728,15 @@ static int digest_update_inner(EVP_MD_CTX *ctx, const void *data, size_t data_le
return 1; do_soft_digest: - if (priv->state == SEC_DIGEST_FIRST_UPDATING - && priv->data - && priv->last_update_bufflen != 0) { + if (priv->state == SEC_DIGEST_FIRST_UPDATING) { priv->switch_flag = UADK_DO_SOFT; (void)digest_soft_init(priv); - ret = digest_soft_update(priv, priv->data, priv->last_update_bufflen); - if (ret != 1) - return ret; + /* filling buf has been executed */ + if (processing_len < DIGEST_BLOCK_SIZE) { + ret = digest_soft_update(priv, priv->data, DIGEST_BLOCK_SIZE); + if (ret != 1) + return ret; + }
return digest_soft_update(priv, tmpdata, left_len); }
From: Chenghai Huang huangchenghai2@huawei.com
In the decrypted filled data update process, the input size will be zero when the input size is smaller than the block size. As a result, an error message indicating that the output size is 0 is reported by UDAK.
Therefore, it need to check whether the input length is 0 before UADK encryption/decryption.
In addition, if the input length is greater than 0 and smaller than the block size, that is, the length of the data currently to be processed is 0, the data needs to be cached in the buffer through ossl_cipher_trailingdata() and sent to the next step.
Signed-off-by: Chenghai Huang huangchenghai2@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_prov_cipher.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c index 7188954..53ff589 100644 --- a/src/uadk_prov_cipher.c +++ b/src/uadk_prov_cipher.c @@ -679,28 +679,28 @@ static int uadk_prov_do_cipher(struct cipher_priv_ctx *priv, unsigned char *out, out += blksz; }
- if (nextblocks > 0) { - if (!priv->enc && priv->pad && nextblocks == inlen) - nextblocks -= blksz; - outlint += nextblocks; - } + if (nextblocks == 0) + goto out; + + if (!priv->enc && priv->pad && nextblocks == inlen) + nextblocks -= blksz;
if (nextblocks > 0) { ret = uadk_prov_hw_cipher(priv, out, outl, outsize, in, nextblocks); if (ret != UADK_E_SUCCESS) { - fprintf(stderr, "do hw ciphers failed.\n"); + fprintf(stderr, "last block do hw ciphers failed.\n"); if (priv->sw_cipher) goto do_soft; return ret; }
+ outlint += nextblocks; in += nextblocks; inlen -= nextblocks; } - - if (inlen != 0 - && !ossl_cipher_trailingdata(priv->buf, &priv->bufsz, - blksz, &in, &inlen)) +out: + if (inlen != 0 && !ossl_cipher_trailingdata(priv->buf, + &priv->bufsz, blksz, &in, &inlen)) return UADK_E_FAIL;
*outl = outlint;
From: Chenghai Huang huangchenghai2@huawei.com
The ivlen param setting function is added.
In addition, the pad param is missing in the ctx param table. As a result, users cannot set this parameter. This param is added.
Signed-off-by: Chenghai Huang huangchenghai2@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_prov_cipher.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c index 53ff589..8c17d98 100644 --- a/src/uadk_prov_cipher.c +++ b/src/uadk_prov_cipher.c @@ -983,6 +983,8 @@ static int uadk_prov_cipher_dinit(void *vctx, const unsigned char *key, size_t k
static const OSSL_PARAM uadk_prov_settable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), + OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), + OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL), OSSL_PARAM_END };
@@ -996,7 +998,6 @@ static int uadk_prov_cipher_set_ctx_params(void *vctx, const OSSL_PARAM params[] { struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; const OSSL_PARAM *p; - int ret = 1;
if (!vctx) return UADK_E_FAIL; @@ -1027,7 +1028,21 @@ static int uadk_prov_cipher_set_ctx_params(void *vctx, const OSSL_PARAM params[] } }
- return ret; + p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_IVLEN); + if (p != NULL) { + size_t ivlen; + + if (!OSSL_PARAM_get_size_t(p, &ivlen)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return UADK_E_FAIL; + } + if (priv->ivlen != ivlen) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); + return UADK_E_FAIL; + } + } + + return UADK_E_SUCCESS; }
static int uadk_prov_cipher_get_ctx_params(void *vctx, OSSL_PARAM params[]) @@ -1071,6 +1086,7 @@ static int uadk_prov_cipher_get_ctx_params(void *vctx, OSSL_PARAM params[]) static const OSSL_PARAM uadk_prov_default_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), + OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0), OSSL_PARAM_END
From: Chenghai Huang huangchenghai2@huawei.com
The OpenSSL enc tool call EVP_CipherInit_ex() twice. The first time is to initialize the encryption/decryption algorithm, and the second time is to input the key and IV parameters. Therefore, an empty key and iv will be passed in the first call.
A flag bit needs to be added to indicate whether the key and IV have been set. Otherwise, the key and IV that are not set will cause a cipher error.
Signed-off-by: Chenghai Huang huangchenghai2@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_prov_cipher.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c index 8c17d98..68926bc 100644 --- a/src/uadk_prov_cipher.c +++ b/src/uadk_prov_cipher.c @@ -83,6 +83,8 @@ struct cipher_priv_ctx { size_t switch_threshold; unsigned int enc : 1; unsigned int pad : 1; /* Whether padding should be used or not */ + unsigned int key_set : 1; /* Whether key is copied to priv key buffers */ + unsigned int iv_set : 1; /* Whether key is copied to priv iv buffers */ size_t blksize; size_t keylen; size_t ivlen; @@ -272,8 +274,10 @@ static int uadk_prov_cipher_init(struct cipher_priv_ctx *priv, return UADK_E_FAIL; }
- if (iv) + if (iv) { memcpy(priv->iv, iv, ivlen); + priv->iv_set = 1; + }
for (i = 0; i < cipher_counts; i++) { if (priv->nid == cipher_info_table[i].nid) { @@ -289,8 +293,10 @@ static int uadk_prov_cipher_init(struct cipher_priv_ctx *priv, return UADK_E_FAIL; }
- if (key) + if (key) { memcpy(priv->key, key, keylen); + priv->key_set = 1; + }
if (enable_sw_offload) uadk_prov_cipher_sw_init(priv, key, iv); @@ -420,6 +426,11 @@ static int uadk_prov_cipher_ctx_init(struct cipher_priv_ctx *priv) struct sched_params params = {0}; int ret;
+ if (!priv->key_set || (!priv->iv_set && priv->ivlen)) { + fprintf(stderr, "key or iv is not set yet!\n"); + return UADK_E_FAIL; + } + priv->req.iv_bytes = priv->ivlen; priv->req.iv = priv->iv;
From: Chenghai Huang huangchenghai2@huawei.com
The digest update after optimization needs to distinguish whether the buffer is copied. If the buffer is filled, the data in the buffer after the copy will be processed. Otherwise, the remaining data will be processed directly.
Signed-off-by: Chenghai Huang huangchenghai2@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_prov_digest.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/src/uadk_prov_digest.c b/src/uadk_prov_digest.c index bc135cd..eddca1a 100644 --- a/src/uadk_prov_digest.c +++ b/src/uadk_prov_digest.c @@ -356,13 +356,19 @@ static int uadk_digest_update_inner(struct digest_priv_ctx *priv, const void *da uadk_fill_mac_buffer_len(priv);
do { - if (left_len == data_len) { + /* + * If there is data in the buffer, it will be filled and processed. Otherwise, it + * will be processed according to the UADK package len(16M-512Byte). Finally the + * remaining data less than the size of the buffer will be stored in the buffer. + */ + if (priv->last_update_bufflen != 0) { processing_len = DIGEST_BLOCK_SIZE - priv->last_update_bufflen; uadk_memcpy(priv->data + priv->last_update_bufflen, tmpdata, processing_len);
priv->req.in_bytes = DIGEST_BLOCK_SIZE; priv->req.in = priv->data; + priv->last_update_bufflen = 0; } else { if (left_len > BUF_LEN) processing_len = BUF_LEN; @@ -395,14 +401,15 @@ static int uadk_digest_update_inner(struct digest_priv_ctx *priv, const void *da return UADK_DIGEST_SUCCESS;
do_soft_digest: - if (priv->state == SEC_DIGEST_FIRST_UPDATING - && priv->data - && priv->last_update_bufflen != 0) { + if (priv->state == SEC_DIGEST_FIRST_UPDATING) { priv->switch_flag = UADK_DO_SOFT; uadk_digest_soft_init(priv); - ret = uadk_digest_soft_update(priv, priv->data, priv->last_update_bufflen); - if (ret != 1) - return ret; + /* filling buf has been executed */ + if (processing_len < DIGEST_BLOCK_SIZE) { + ret = uadk_digest_soft_update(priv, priv->data, DIGEST_BLOCK_SIZE); + if (ret != 1) + return ret; + }
return uadk_digest_soft_update(priv, tmpdata, left_len); }
From: Chenghai Huang huangchenghai2@huawei.com
Extract hardware initialization functions to separate functions. And add the unlock function when the process fork.
Signed-off-by: Chenghai Huang huangchenghai2@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_prov_cipher.c | 78 +++++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 27 deletions(-)
diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c index 68926bc..69cd114 100644 --- a/src/uadk_prov_cipher.c +++ b/src/uadk_prov_cipher.c @@ -55,6 +55,9 @@ #define PROV_CIPHER_FLAG_TLS1_MULTIBLOCK 0x0008 #define PROV_CIPHER_FLAG_RAND_KEY 0x0010
+#define UADK_CIPHER_DEF_CTXS 2 +#define UADK_CIPHER_OP_NUM 1 + /* Internal flags that are only used within the provider */ #define PROV_CIPHER_FLAG_VARIABLE_LENGTH 0x0100 #define PROV_CIPHER_FLAG_INVERSE_CIPHER 0x0200 @@ -242,7 +245,9 @@ static int uadk_prov_cipher_soft_work(struct cipher_priv_ctx *priv, unsigned cha return UADK_E_SUCCESS; }
-static int uadk_cipher_env_poll(void *ctx) +static void uadk_prov_cipher_dev_init(struct cipher_priv_ctx *priv); + +static int uadk_cipher_poll(void *ctx) { __u64 rx_cnt = 0; __u32 recv = 0; @@ -299,7 +304,9 @@ static int uadk_prov_cipher_init(struct cipher_priv_ctx *priv, }
if (enable_sw_offload) - uadk_prov_cipher_sw_init(priv, key, iv); + return uadk_prov_cipher_sw_init(priv, key, iv); + + uadk_prov_cipher_dev_init(priv);
return UADK_E_SUCCESS; } @@ -421,61 +428,78 @@ static int uadk_do_cipher_async(struct cipher_priv_ctx *priv, struct async_op *o return UADK_E_SUCCESS; }
-static int uadk_prov_cipher_ctx_init(struct cipher_priv_ctx *priv) +static void uadk_cipher_mutex_infork(void) { - struct sched_params params = {0}; - int ret; - - if (!priv->key_set || (!priv->iv_set && priv->ivlen)) { - fprintf(stderr, "key or iv is not set yet!\n"); - return UADK_E_FAIL; - } - - priv->req.iv_bytes = priv->ivlen; - priv->req.iv = priv->iv; + /* Release the replication lock of the child process */ + pthread_mutex_unlock(&cipher_mutex); +}
- if (priv->switch_flag == UADK_DO_SOFT) - return; +static void uadk_prov_cipher_dev_init(struct cipher_priv_ctx *priv) +{ + int ret;
+ pthread_atfork(NULL, NULL, uadk_cipher_mutex_infork); pthread_mutex_lock(&cipher_mutex); if (prov.pid != getpid()) { struct wd_ctx_nums *ctx_set_num; struct wd_ctx_params cparams = {0};
- ctx_set_num = calloc(1, sizeof(*ctx_set_num)); + ctx_set_num = calloc(UADK_CIPHER_OP_NUM, sizeof(*ctx_set_num)); if (!ctx_set_num) { fprintf(stderr, "failed to alloc ctx_set_size!\n"); - return; + goto init_err; }
- cparams.op_type_num = 1; + cparams.op_type_num = UADK_CIPHER_OP_NUM; cparams.ctx_set_num = ctx_set_num; cparams.bmp = numa_allocate_nodemask(); if (!cparams.bmp) { fprintf(stderr, "failed to create nodemask!\n"); free(ctx_set_num); - return; + goto init_err; }
numa_bitmask_setall(cparams.bmp);
- ctx_set_num[0].sync_ctx_num = 2; - ctx_set_num[0].async_ctx_num = 2; + ctx_set_num[0].sync_ctx_num = UADK_CIPHER_DEF_CTXS; + ctx_set_num[0].async_ctx_num = UADK_CIPHER_DEF_CTXS; + ctx_set_num[1].sync_ctx_num = UADK_CIPHER_DEF_CTXS; + ctx_set_num[1].async_ctx_num = UADK_CIPHER_DEF_CTXS;
- ret = wd_cipher_init2_(priv->alg_name, 0, 0, &cparams); + ret = wd_cipher_init2_(priv->alg_name, TASK_MIX, SCHED_POLICY_RR, &cparams); numa_free_nodemask(cparams.bmp); free(ctx_set_num);
if (unlikely(ret)) { - if (priv->sw_cipher) - priv->switch_flag = UADK_DO_SOFT; - pthread_mutex_unlock(&cipher_mutex); - return; + fprintf(stderr, "failed to init cipher!\n"); + goto init_err; } + prov.pid = getpid(); - async_register_poll_fn(ASYNC_TASK_CIPHER, uadk_cipher_env_poll); + async_register_poll_fn(ASYNC_TASK_CIPHER, uadk_cipher_poll); } + +init_err: pthread_mutex_unlock(&cipher_mutex); +} + +static int uadk_prov_cipher_ctx_init(struct cipher_priv_ctx *priv) +{ + struct sched_params params = {0}; + int ret; + + if (!priv->key_set || (!priv->iv_set && priv->ivlen)) { + fprintf(stderr, "key or iv is not set yet!\n"); + return UADK_E_FAIL; + } + + priv->req.iv_bytes = priv->ivlen; + priv->req.iv = priv->iv; + + if (priv->switch_flag == UADK_DO_SOFT) + return UADK_E_FAIL; + + uadk_prov_cipher_dev_init(priv);
/* dec and enc use the same op */ params.type = 0;
From: Chenghai Huang huangchenghai2@huawei.com
When the num of recv packets is greater than the expected number. The condition that expected nums equal to actual nums, for exiting the poll loop will cause a long retry loop.
Therefore, the loop exit condition is modified, and full_sem is reduced when no task needs to be queried.
Signed-off-by: Chenghai Huang huangchenghai2@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_async.c | 6 ++++-- src/uadk_cipher.c | 2 +- src/uadk_prov_cipher.c | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/uadk_async.c b/src/uadk_async.c index a36a394..04e52f8 100644 --- a/src/uadk_async.c +++ b/src/uadk_async.c @@ -322,7 +322,7 @@ static void *async_poll_process_func(void *args) { struct async_poll_task *task; struct async_op *op; - int ret, idx; + int ret, idx, empty_num;
while (uadk_e_get_async_poll_state()) { if (sem_wait(&poll_queue.full_sem)) { @@ -334,7 +334,9 @@ static void *async_poll_process_func(void *args)
task = async_get_queue_task(); if (!task) { - (void)sem_post(&poll_queue.full_sem); + (void)sem_getvalue(&poll_queue.empty_sem, &empty_num); + if (empty_num != ASYNC_QUEUE_TASK_NUM) + (void)sem_post(&poll_queue.full_sem); usleep(1); continue; } diff --git a/src/uadk_cipher.c b/src/uadk_cipher.c index ff53e0b..44b0aa0 100644 --- a/src/uadk_cipher.c +++ b/src/uadk_cipher.c @@ -362,7 +362,7 @@ static int uadk_e_cipher_env_poll(void *ctx)
do { ret = wd_cipher_poll(expt, &recv); - if (ret < 0 || recv == expt) + if (ret < 0 || recv >= expt) return ret; rx_cnt++; } while (rx_cnt < ENGINE_ENV_RECV_MAX_CNT); diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c index 69cd114..70e9e89 100644 --- a/src/uadk_prov_cipher.c +++ b/src/uadk_prov_cipher.c @@ -257,7 +257,7 @@ static int uadk_cipher_poll(void *ctx)
do { ret = wd_cipher_poll(expt, &recv); - if (ret < 0 || recv == expt) + if (ret < 0 || recv >= expt) return ret; rx_cnt++; } while (rx_cnt < ENGINE_RECV_MAX_CNT);
The key generation and key derivation functions of the x25519 and x448 algorithms are implemented separately before. This modification combines the similar logic to simplify the code, reducing code duplication ratio.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_ecx.c | 289 +++++++++++++++++-------------------------------- 1 file changed, 100 insertions(+), 189 deletions(-)
diff --git a/src/uadk_ecx.c b/src/uadk_ecx.c index 2f9f619..ae91e88 100644 --- a/src/uadk_ecx.c +++ b/src/uadk_ecx.c @@ -110,21 +110,6 @@ static int x25519_init(EVP_PKEY_CTX *ctx) return UADK_E_SUCCESS; }
-static void x25519_uninit(EVP_PKEY_CTX *ctx) -{ - struct ecx_ctx *x25519_ctx = EVP_PKEY_CTX_get_data(ctx); - - if (!x25519_ctx) - return; - - if (x25519_ctx->sess) - wd_ecc_free_sess(x25519_ctx->sess); - - free(x25519_ctx); - - EVP_PKEY_CTX_set_data(ctx, NULL); -} - static int x448_init(EVP_PKEY_CTX *ctx) { struct wd_ecc_sess_setup setup = {0}; @@ -164,21 +149,71 @@ static int x448_init(EVP_PKEY_CTX *ctx) return UADK_E_SUCCESS; }
-static void x448_uninit(EVP_PKEY_CTX *ctx) +static int ecx_get_nid(EVP_PKEY_CTX *ctx) +{ + const EVP_PKEY_METHOD **pmeth_from_ctx; + int nid; + + pmeth_from_ctx = (const EVP_PKEY_METHOD **)ctx; + + EVP_PKEY_meth_get0_info(&nid, NULL, *pmeth_from_ctx); + if (nid != EVP_PKEY_X25519 && nid != EVP_PKEY_X448) + return UADK_E_FAIL; + + return nid; +} + +static int ecx_init(EVP_PKEY_CTX *ctx) { - struct ecx_ctx *x448_ctx = EVP_PKEY_CTX_get_data(ctx); + int nid = ecx_get_nid(ctx);
- if (!x448_ctx) + switch (nid) { + case EVP_PKEY_X25519: + return x25519_init(ctx); + case EVP_PKEY_X448: + return x448_init(ctx); + default: + fprintf(stderr, "failed to init ecx\n"); + } + + return UADK_E_FAIL; +} + +static void ecx_uninit(EVP_PKEY_CTX *ctx) +{ + struct ecx_ctx *ecx_ctx = EVP_PKEY_CTX_get_data(ctx); + + if (!ecx_ctx) return;
- if (x448_ctx->sess) - wd_ecc_free_sess(x448_ctx->sess); + if (ecx_ctx->sess) + wd_ecc_free_sess(ecx_ctx->sess);
- free(x448_ctx); + free(ecx_ctx);
EVP_PKEY_CTX_set_data(ctx, NULL); }
+static int ecx_set_ctx(EVP_PKEY_CTX *ctx, struct ecx_ctx *ecx_ctx) +{ + int nid = ecx_get_nid(ctx); + + switch (nid) { + case EVP_PKEY_X25519: + ecx_ctx->nid = EVP_PKEY_X25519; + ecx_ctx->key_size = X25519_KEYLEN; + return UADK_E_SUCCESS; + case EVP_PKEY_X448: + ecx_ctx->nid = EVP_PKEY_X448; + ecx_ctx->key_size = X448_KEYLEN; + return UADK_E_SUCCESS; + default: + fprintf(stderr, "failed to set ecx ctx\n"); + } + + return UADK_E_FAIL; +} + static int ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { if (type == EVP_PKEY_CTRL_PEER_KEY) @@ -217,20 +252,6 @@ static int ecx_keygen_init_iot(handle_t sess, struct wd_ecc_req *req) return UADK_E_SUCCESS; }
-static int ecx_get_nid(EVP_PKEY_CTX *ctx) -{ - const EVP_PKEY_METHOD **pmeth_from_ctx; - int nid; - - pmeth_from_ctx = (const EVP_PKEY_METHOD **)ctx; - - EVP_PKEY_meth_get0_info(&nid, NULL, *pmeth_from_ctx); - if (nid != EVP_PKEY_X25519 && nid != EVP_PKEY_X448) - return UADK_E_FAIL; - - return nid; -} - static int ecx_create_privkey(struct ecx_key **ecx_key, __u32 key_size) { unsigned char *privkey; @@ -383,7 +404,7 @@ static int openssl_do_ecx_genkey(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) return (*sw_fn_ptr)(ctx, pkey); }
-static int x25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +static int ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { struct ecx_ctx *keygen_ctx = NULL; struct ecx_key *ecx_key = NULL; @@ -394,73 +415,17 @@ static int x25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) if (!ret) goto do_soft;
- ret = x25519_init(ctx); + ret = ecx_init(ctx); if (!ret) goto do_soft;
keygen_ctx = EVP_PKEY_CTX_get_data(ctx); if (!keygen_ctx) - goto do_soft; - keygen_ctx->nid = EVP_PKEY_X25519; - keygen_ctx->key_size = X25519_KEYLEN; - - ret = ecx_create_privkey(&ecx_key, keygen_ctx->key_size); - if (!ret) goto uninit_ctx;
- ret = ecx_keygen_init_iot(keygen_ctx->sess, &req); - if (!ret) - goto free_key; - - ret = ecx_keygen_set_private_key(keygen_ctx, ecx_key); - if (!ret) - goto uninit_iot; - - ret = uadk_ecc_crypto(keygen_ctx->sess, &req, (void *)keygen_ctx->sess); - if (!ret) - goto uninit_iot; - - ret = ecx_keygen_set_pkey(pkey, keygen_ctx, &req, ecx_key); - if (!ret) - goto uninit_iot; - - wd_ecc_del_out(keygen_ctx->sess, req.dst); - x25519_uninit(ctx); - - return ret; - -uninit_iot: - wd_ecc_del_out(keygen_ctx->sess, req.dst); -free_key: - OPENSSL_secure_free(ecx_key->privkey); - OPENSSL_free(ecx_key); -uninit_ctx: - x25519_uninit(ctx); -do_soft: - fprintf(stderr, "switch to execute openssl software calculation.\n"); - return openssl_do_ecx_genkey(ctx, pkey); -} - -static int x448_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - struct ecx_ctx *keygen_ctx = NULL; - struct ecx_key *ecx_key = NULL; - struct wd_ecc_req req = {0}; - int ret; - - ret = ecx_genkey_check(ctx, pkey); - if (!ret) - goto do_soft; - - ret = x448_init(ctx); + ret = ecx_set_ctx(ctx, keygen_ctx); if (!ret) - goto do_soft; - - keygen_ctx = EVP_PKEY_CTX_get_data(ctx); - if (!keygen_ctx) goto uninit_ctx; - keygen_ctx->nid = EVP_PKEY_X448; - keygen_ctx->key_size = X448_KEYLEN;
ret = ecx_create_privkey(&ecx_key, keygen_ctx->key_size); if (!ret) @@ -483,7 +448,7 @@ static int x448_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) goto uninit_iot;
wd_ecc_del_out(keygen_ctx->sess, req.dst); - x448_uninit(ctx); + ecx_uninit(ctx);
return ret;
@@ -493,7 +458,7 @@ free_key: OPENSSL_secure_free(ecx_key->privkey); OPENSSL_free(ecx_key); uninit_ctx: - x448_uninit(ctx); + ecx_uninit(ctx); do_soft: fprintf(stderr, "switch to execute openssl software calculation.\n"); return openssl_do_ecx_genkey(ctx, pkey); @@ -633,79 +598,6 @@ static void x25519_pad_out_key(unsigned char *dst_key, unsigned char *src_key, } }
-/** - * x25519_derive: generate shared key. - * @ctx: the X25519 key ctx, contain own private key, - * public key and peer public key. - * @key: the output shared key. - * @keylen: the length of output shared key. - */ -static int x25519_derive(EVP_PKEY_CTX *ctx, unsigned char *key, - size_t *keylen) -{ - struct ecx_key *peer_ecx_key = NULL; - struct wd_ecc_point *s_key = NULL; - struct ecx_ctx *derive_ctx = NULL; - struct ecx_key *ecx_key = NULL; - struct wd_ecc_req req = {0}; - int ret; - - ret = x25519_init(ctx); - if (!ret) - goto do_soft; - - if (!key || !(*keylen)) { - *keylen = (size_t) X25519_KEYLEN; - x25519_uninit(ctx); - return UADK_E_SUCCESS; - } - - derive_ctx = EVP_PKEY_CTX_get_data(ctx); - if (!derive_ctx) - goto uninit_ctx; - derive_ctx->nid = EVP_PKEY_X25519; - derive_ctx->key_size = X25519_KEYLEN; - - ret = ecx_get_key(ctx, &ecx_key, &peer_ecx_key); - if (!ret) - goto uninit_ctx; - - ret = ecx_compkey_init_iot(derive_ctx, &req, peer_ecx_key, ecx_key); - if (!ret) - goto uninit_ctx; - - ret = ecx_derive_set_private_key(derive_ctx, ecx_key); - if (!ret) - goto uninit_iot; - - ret = uadk_ecc_crypto(derive_ctx->sess, &req, (void *)derive_ctx); - if (!ret) - goto uninit_iot; - - wd_ecxdh_get_out_params(req.dst, &s_key); - if (!s_key) - goto uninit_iot; - - ret = reverse_bytes((unsigned char *)s_key->x.data, s_key->x.dsize); - if (!ret) - goto uninit_iot; - - x25519_pad_out_key(key, (unsigned char *)s_key->x.data, s_key->x.dsize); - - ecx_compkey_uninit_iot(derive_ctx->sess, &req); - x25519_uninit(ctx); - - return ret; - -uninit_iot: - ecx_compkey_uninit_iot(derive_ctx->sess, &req); -uninit_ctx: - x25519_uninit(ctx); -do_soft: - fprintf(stderr, "switch to execute openssl software calculation.\n"); - return openssl_do_derive(ctx, key, keylen); -} - static void x448_pad_out_key(unsigned char *dst_key, unsigned char *src_key, size_t len) { @@ -719,15 +611,28 @@ static void x448_pad_out_key(unsigned char *dst_key, unsigned char *src_key, } }
+static void ecx_pad_out_key(unsigned char *dst_key, unsigned char *src_key, + size_t len, int nid) +{ + if (nid == EVP_PKEY_X25519) { + x25519_pad_out_key(dst_key, src_key, len); + return; + } + + if (nid == EVP_PKEY_X448) { + x448_pad_out_key(dst_key, src_key, len); + return; + } +} + /** - * x448_derive: generate shared key. - * @ctx: the X448 key ctx, contain own private key, + * ecx_derive: generate shared key. + * @ctx: the ecx key ctx, contain own private key, * public key and peer public key. * @key: the output shared key. * @keylen: the length of output shared key. */ -static int x448_derive(EVP_PKEY_CTX *ctx, unsigned char *key, - size_t *keylen) +static int ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) { struct ecx_key *peer_ecx_key = NULL; struct wd_ecc_point *s_key = NULL; @@ -736,21 +641,27 @@ static int x448_derive(EVP_PKEY_CTX *ctx, unsigned char *key, struct wd_ecc_req req = {0}; int ret;
- ret = x448_init(ctx); - if (!ret) + if (!ctx) { + fprintf(stderr, "invalid: ctx is NULL\n"); goto do_soft; - - if (!key || !(*keylen)) { - *keylen = (size_t) X448_KEYLEN; - x448_uninit(ctx); - return UADK_E_SUCCESS; }
+ ret = ecx_init(ctx); + if (!ret) + goto do_soft; + derive_ctx = EVP_PKEY_CTX_get_data(ctx); if (!derive_ctx) goto uninit_ctx; - derive_ctx->nid = EVP_PKEY_X448; - derive_ctx->key_size = X448_KEYLEN; + + ret = ecx_set_ctx(ctx, derive_ctx); + if (!ret) + goto uninit_ctx; + + if (!key || !(*keylen)) { + *keylen = (size_t)derive_ctx->key_size; + return UADK_E_SUCCESS; + }
ret = ecx_get_key(ctx, &ecx_key, &peer_ecx_key); if (!ret) @@ -776,17 +687,17 @@ static int x448_derive(EVP_PKEY_CTX *ctx, unsigned char *key, if (!ret) goto uninit_iot;
- x448_pad_out_key(key, (unsigned char *)s_key->x.data, s_key->x.dsize); + ecx_pad_out_key(key, (unsigned char *)s_key->x.data, s_key->x.dsize, derive_ctx->nid);
ecx_compkey_uninit_iot(derive_ctx->sess, &req); - x448_uninit(ctx); + ecx_uninit(ctx);
return ret;
uninit_iot: ecx_compkey_uninit_iot(derive_ctx->sess, &req); uninit_ctx: - x448_uninit(ctx); + ecx_uninit(ctx); do_soft: fprintf(stderr, "switch to execute openssl software calculation.\n"); return openssl_do_derive(ctx, key, keylen); @@ -821,8 +732,8 @@ int uadk_x25519_create_pmeth(struct uadk_pkey_meth *pkey_meth) }
EVP_PKEY_meth_set_ctrl(meth, ecx_ctrl, NULL); - EVP_PKEY_meth_set_keygen(meth, NULL, x25519_keygen); - EVP_PKEY_meth_set_derive(meth, NULL, x25519_derive); + EVP_PKEY_meth_set_keygen(meth, NULL, ecx_keygen); + EVP_PKEY_meth_set_derive(meth, NULL, ecx_derive);
pkey_meth->x25519 = meth;
@@ -867,8 +778,8 @@ int uadk_x448_create_pmeth(struct uadk_pkey_meth *pkey_meth) }
EVP_PKEY_meth_set_ctrl(meth, ecx_ctrl, NULL); - EVP_PKEY_meth_set_keygen(meth, NULL, x448_keygen); - EVP_PKEY_meth_set_derive(meth, NULL, x448_derive); + EVP_PKEY_meth_set_keygen(meth, NULL, ecx_keygen); + EVP_PKEY_meth_set_derive(meth, NULL, ecx_derive);
pkey_meth->x448 = meth;
The length of the pubkey get from wd_ecxdh_get_out_params() may not be 'key_size', the actual value in 'dsize' may smaller than 'key_size'. So copy 'key_size' length to ecx_key->pubkey will make the reverse_bytes() operates on incorrect pubkey length, which will make the actual value changed. Fix this issue by using the length filled in 'dsize'.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_ecx.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/uadk_ecx.c b/src/uadk_ecx.c index ae91e88..011f733 100644 --- a/src/uadk_ecx.c +++ b/src/uadk_ecx.c @@ -311,21 +311,21 @@ static int ecx_keygen_set_private_key(struct ecx_ctx *ecx_ctx, static int ecx_keygen_set_pkey(EVP_PKEY *pkey, struct ecx_ctx *ecx_ctx, struct wd_ecc_req *req, struct ecx_key *ecx_key) { - __u32 key_size = ecx_ctx->key_size; struct wd_ecc_point *pubkey = NULL; int ret;
- if (key_size > ECX_MAX_KEYLEN) { - fprintf(stderr, "invalid key size, key_size = %u\n", key_size); - return UADK_E_FAIL; - } - wd_ecxdh_get_out_params(req->dst, &pubkey); if (!pubkey) { fprintf(stderr, "failed to get pubkey\n"); return UADK_E_FAIL; }
+ if (pubkey->x.dsize >= ECX_MAX_KEYLEN) { + fprintf(stderr, "invalid key size, pubkey->x.dsize = %u\n", + pubkey->x.dsize); + return UADK_E_FAIL; + } + memcpy(ecx_key->pubkey, (const unsigned char *)pubkey->x.data, pubkey->x.dsize); /* Trans public key from big-endian to little-endian */ ret = reverse_bytes(ecx_key->pubkey, pubkey->x.dsize); @@ -334,7 +334,7 @@ static int ecx_keygen_set_pkey(EVP_PKEY *pkey, struct ecx_ctx *ecx_ctx, return UADK_E_FAIL; } /* Trans private key from big-endian to little-endian */ - ret = reverse_bytes(ecx_key->privkey, key_size); + ret = reverse_bytes(ecx_key->privkey, ecx_ctx->key_size); if (!ret) { fprintf(stderr, "failed to trans private key\n"); return UADK_E_FAIL;
From: Chenghai Huang huangchenghai2@huawei.com
Add AES-128-CBC-CTS AES-192-CBC-CTS AES-256-CBC-CTS to uadk_provider. Each alg has 3 modes, such as CS1, CS2, and CS3.
The default mode is CS1. You can select a mode by setting the OSSL_CIPHER_PARAM_CTS_MODE parameter.
Signed-off-by: Chenghai Huang huangchenghai2@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_prov.h | 3 + src/uadk_prov_cipher.c | 307 ++++++++++++++++++++++++++++++----------- src/uadk_prov_init.c | 6 + 3 files changed, 232 insertions(+), 84 deletions(-)
diff --git a/src/uadk_prov.h b/src/uadk_prov.h index 3655437..fa649ed 100644 --- a/src/uadk_prov.h +++ b/src/uadk_prov.h @@ -131,6 +131,9 @@ extern const OSSL_DISPATCH uadk_sha512_256_functions[FUNC_MAX_NUM]; extern const OSSL_DISPATCH uadk_aes_128_cbc_functions[FUNC_MAX_NUM]; extern const OSSL_DISPATCH uadk_aes_192_cbc_functions[FUNC_MAX_NUM]; extern const OSSL_DISPATCH uadk_aes_256_cbc_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_aes_128_cts_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_aes_192_cts_functions[FUNC_MAX_NUM]; +extern const OSSL_DISPATCH uadk_aes_256_cts_functions[FUNC_MAX_NUM]; extern const OSSL_DISPATCH uadk_aes_128_ecb_functions[FUNC_MAX_NUM]; extern const OSSL_DISPATCH uadk_aes_192_ecb_functions[FUNC_MAX_NUM]; extern const OSSL_DISPATCH uadk_aes_256_ecb_functions[FUNC_MAX_NUM]; diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c index 70e9e89..623347e 100644 --- a/src/uadk_prov_cipher.c +++ b/src/uadk_prov_cipher.c @@ -31,6 +31,7 @@
#define UADK_DO_SOFT (-0xE0) #define UADK_DO_HW (-0xF0) +#define OSSL_NELEM(x) (sizeof(x)/sizeof((x)[0])) #define CTX_SYNC_ENC 0 #define CTX_SYNC_DEC 1 #define CTX_ASYNC_ENC 2 @@ -58,6 +59,45 @@ #define UADK_CIPHER_DEF_CTXS 2 #define UADK_CIPHER_OP_NUM 1
+/* OSSL_CIPHER_PARAM_CTS_MODE Values */ +# define OSSL_CIPHER_CTS_MODE_CS1 "CS1" +# define OSSL_CIPHER_CTS_MODE_CS2 "CS2" +# define OSSL_CIPHER_CTS_MODE_CS3 "CS3" + +# define UADK_CIPHER_CTS_CS1_NAME "cbc-cs1(aes)" +# define UADK_CIPHER_CTS_CS2_NAME "cbc-cs2(aes)" +# define UADK_CIPHER_CTS_CS3_NAME "cbc-cs3(aes)" + +enum uadk_cipher_alg_id { + ID_aes_128_ecb, + ID_aes_192_ecb, + ID_aes_256_ecb, + ID_aes_128_cbc, + ID_aes_192_cbc, + ID_aes_256_cbc, + ID_aes_128_cts, + ID_aes_192_cts, + ID_aes_256_cts, + ID_aes_128_xts, + ID_aes_256_xts, + ID_aes_128_ctr, + ID_aes_192_ctr, + ID_aes_256_ctr, + ID_aes_128_ofb128, + ID_aes_192_ofb128, + ID_aes_256_ofb128, + ID_aes_128_cfb128, + ID_aes_192_cfb128, + ID_aes_256_cfb128, + ID_sm4_cbc, + ID_sm4_ofb128, + ID_sm4_cfb128, + ID_sm4_ecb, + ID_sm4_ctr, + ID_des_ede3_cbc, + ID_des_ede3_ecb, +}; + /* Internal flags that are only used within the provider */ #define PROV_CIPHER_FLAG_VARIABLE_LENGTH 0x0100 #define PROV_CIPHER_FLAG_INVERSE_CIPHER 0x0200 @@ -86,6 +126,7 @@ struct cipher_priv_ctx { size_t switch_threshold; unsigned int enc : 1; unsigned int pad : 1; /* Whether padding should be used or not */ + unsigned int cts_mode; /* Use to set the type for CTS modes */ unsigned int key_set : 1; /* Whether key is copied to priv key buffers */ unsigned int iv_set : 1; /* Whether key is copied to priv iv buffers */ size_t blksize; @@ -103,102 +144,148 @@ struct cipher_info { };
static struct cipher_info cipher_info_table[] = { - { NID_aes_128_ecb, WD_CIPHER_AES, WD_CIPHER_ECB, 16}, - { NID_aes_192_ecb, WD_CIPHER_AES, WD_CIPHER_ECB, 16}, - { NID_aes_256_ecb, WD_CIPHER_AES, WD_CIPHER_ECB, 16}, - { NID_aes_128_cbc, WD_CIPHER_AES, WD_CIPHER_CBC, 16}, - { NID_aes_192_cbc, WD_CIPHER_AES, WD_CIPHER_CBC, 64}, - { NID_aes_256_cbc, WD_CIPHER_AES, WD_CIPHER_CBC, 64}, - { NID_aes_128_xts, WD_CIPHER_AES, WD_CIPHER_XTS, 32}, - { NID_aes_256_xts, WD_CIPHER_AES, WD_CIPHER_XTS, 512}, - { NID_sm4_cbc, WD_CIPHER_SM4, WD_CIPHER_CBC, 16}, - { NID_des_ede3_cbc, WD_CIPHER_3DES, WD_CIPHER_CBC, 16}, - { NID_des_ede3_ecb, WD_CIPHER_3DES, WD_CIPHER_ECB, 16}, - { NID_aes_128_ctr, WD_CIPHER_AES, WD_CIPHER_CTR, 64}, - { NID_aes_192_ctr, WD_CIPHER_AES, WD_CIPHER_CTR, 64}, - { NID_aes_256_ctr, WD_CIPHER_AES, WD_CIPHER_CTR, 64}, - { NID_aes_128_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB, 16}, - { NID_aes_192_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB, 16}, - { NID_aes_256_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB, 16}, - { NID_aes_128_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB, 16}, - { NID_aes_192_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB, 16}, - { NID_aes_256_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB, 16}, - { NID_sm4_ofb128, WD_CIPHER_SM4, WD_CIPHER_OFB, 16}, - { NID_sm4_cfb128, WD_CIPHER_SM4, WD_CIPHER_CFB, 16}, - { NID_sm4_ecb, WD_CIPHER_SM4, WD_CIPHER_ECB, 16}, - { NID_sm4_ctr, WD_CIPHER_SM4, WD_CIPHER_CTR, 16}, + { ID_aes_128_ecb, WD_CIPHER_AES, WD_CIPHER_ECB, 16}, + { ID_aes_192_ecb, WD_CIPHER_AES, WD_CIPHER_ECB, 16}, + { ID_aes_256_ecb, WD_CIPHER_AES, WD_CIPHER_ECB, 16}, + { ID_aes_128_cbc, WD_CIPHER_AES, WD_CIPHER_CBC, 16}, + { ID_aes_192_cbc, WD_CIPHER_AES, WD_CIPHER_CBC, 64}, + { ID_aes_256_cbc, WD_CIPHER_AES, WD_CIPHER_CBC, 64}, + { ID_aes_128_cts, WD_CIPHER_AES, WD_CIPHER_CBC_CS1, 16}, + { ID_aes_192_cts, WD_CIPHER_AES, WD_CIPHER_CBC_CS1, 16}, + { ID_aes_256_cts, WD_CIPHER_AES, WD_CIPHER_CBC_CS1, 64}, + { ID_aes_128_xts, WD_CIPHER_AES, WD_CIPHER_XTS, 32}, + { ID_aes_256_xts, WD_CIPHER_AES, WD_CIPHER_XTS, 512}, + { ID_aes_128_ctr, WD_CIPHER_AES, WD_CIPHER_CTR, 64}, + { ID_aes_192_ctr, WD_CIPHER_AES, WD_CIPHER_CTR, 64}, + { ID_aes_256_ctr, WD_CIPHER_AES, WD_CIPHER_CTR, 64}, + { ID_aes_128_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB, 16}, + { ID_aes_192_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB, 16}, + { ID_aes_256_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB, 16}, + { ID_aes_128_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB, 16}, + { ID_aes_192_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB, 16}, + { ID_aes_256_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB, 16}, + { ID_sm4_cbc, WD_CIPHER_SM4, WD_CIPHER_CBC, 16}, + { ID_sm4_ofb128, WD_CIPHER_SM4, WD_CIPHER_OFB, 16}, + { ID_sm4_cfb128, WD_CIPHER_SM4, WD_CIPHER_CFB, 16}, + { ID_sm4_ecb, WD_CIPHER_SM4, WD_CIPHER_ECB, 16}, + { ID_sm4_ctr, WD_CIPHER_SM4, WD_CIPHER_CTR, 16}, + { ID_des_ede3_cbc, WD_CIPHER_3DES, WD_CIPHER_CBC, 16}, + { ID_des_ede3_ecb, WD_CIPHER_3DES, WD_CIPHER_ECB, 16}, };
+struct cts_mode_name2id_st { + unsigned int id; + const char *ossl_mode_name; + const char *uadk_alg_name; +}; + +static struct cts_mode_name2id_st cts_modes[] = { + { WD_CIPHER_CBC_CS1, OSSL_CIPHER_CTS_MODE_CS1, UADK_CIPHER_CTS_CS1_NAME }, + { WD_CIPHER_CBC_CS2, OSSL_CIPHER_CTS_MODE_CS2, UADK_CIPHER_CTS_CS2_NAME }, + { WD_CIPHER_CBC_CS3, OSSL_CIPHER_CTS_MODE_CS3, UADK_CIPHER_CTS_CS3_NAME }, +}; + +const char *ossl_cipher_cbc_cts_mode_id2name(unsigned int id) +{ + size_t i; + + for (i = 0; i < OSSL_NELEM(cts_modes); ++i) { + if (cts_modes[i].id == id) + return cts_modes[i].ossl_mode_name; + } + return NULL; +} + +int ossl_cipher_cbc_cts_mode_name2id(const char *name) +{ + size_t i; + + for (i = 0; i < OSSL_NELEM(cts_modes); ++i) { + if (OPENSSL_strcasecmp(name, cts_modes[i].ossl_mode_name) == 0) + return (int)cts_modes[i].id; + } + return -1; +} + static int uadk_fetch_sw_cipher(struct cipher_priv_ctx *priv) { if (priv->sw_cipher) return UADK_E_SUCCESS;
switch (priv->nid) { - case NID_aes_128_cbc: + case ID_aes_128_cbc: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-128-CBC", "provider=default"); break; - case NID_aes_192_cbc: + case ID_aes_192_cbc: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-192-CBC", "provider=default"); break; - case NID_aes_256_cbc: + case ID_aes_256_cbc: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-CBC", "provider=default"); break; - case NID_aes_128_ecb: + case ID_aes_128_cts: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-128-CBC-CTS", "provider=default"); + break; + case ID_aes_192_cts: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-192-CBC-CTS", "provider=default"); + break; + case ID_aes_256_cts: + priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-CBC-CTS", "provider=default"); + break; + case ID_aes_128_ecb: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-128-ECB", "provider=default"); break; - case NID_aes_192_ecb: + case ID_aes_192_ecb: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-192-ECB", "provider=default"); break; - case NID_aes_256_ecb: + case ID_aes_256_ecb: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-ECB", "provider=default"); break; - case NID_sm4_cbc: + case ID_sm4_cbc: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "SM4-CBC", "provider=default"); break; - case NID_sm4_ecb: + case ID_sm4_ecb: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "SM4-ECB", "provider=default"); break; - case NID_des_ede3_cbc: + case ID_des_ede3_cbc: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "DES-EDE3-CBC", "provider=default"); break; - case NID_des_ede3_ecb: + case ID_des_ede3_ecb: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "DES-EDE3-ECB", "provider=default"); break; - case NID_aes_128_ctr: + case ID_aes_128_ctr: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-128-CTR", "provider=default"); break; - case NID_aes_192_ctr: + case ID_aes_192_ctr: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-192-CTR", "provider=default"); break; - case NID_aes_256_ctr: + case ID_aes_256_ctr: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-CTR", "provider=default"); break; - case NID_aes_128_ofb128: + case ID_aes_128_ofb128: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-128-OFB", "provider=default"); break; - case NID_aes_192_ofb128: + case ID_aes_192_ofb128: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-192-OFB", "provider=default"); break; - case NID_aes_256_ofb128: + case ID_aes_256_ofb128: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-OFB", "provider=default"); break; - case NID_aes_128_cfb128: + case ID_aes_128_cfb128: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-128-CFB", "provider=default"); break; - case NID_aes_192_cfb128: + case ID_aes_192_cfb128: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-192-CFB", "provider=default"); break; - case NID_aes_256_cfb128: + case ID_aes_256_cfb128: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "AES-256-CFB", "provider=default"); break; - case NID_sm4_ofb128: + case ID_sm4_ofb128: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "SM4-OFB", "provider=default"); break; - case NID_sm4_cfb128: + case ID_sm4_cfb128: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "SM4-CFB", "provider=default"); break; - case NID_sm4_ctr: + case ID_sm4_ctr: priv->sw_cipher = EVP_CIPHER_fetch(NULL, "SM4-CTR", "provider=default"); break; default: @@ -267,23 +354,12 @@ static int uadk_cipher_poll(void *ctx) return -ETIMEDOUT; }
-static int uadk_prov_cipher_init(struct cipher_priv_ctx *priv, - const unsigned char *key, size_t keylen, - const unsigned char *iv, size_t ivlen) +static int uadk_get_cipher_info(struct cipher_priv_ctx *priv) { int cipher_counts = ARRAY_SIZE(cipher_info_table); + int nid = priv->nid; int i;
- if (ivlen > IV_LEN || keylen > MAX_KEY_LEN) { - fprintf(stderr, "invalid keylen or ivlen.\n"); - return UADK_E_FAIL; - } - - if (iv) { - memcpy(priv->iv, iv, ivlen); - priv->iv_set = 1; - } - for (i = 0; i < cipher_counts; i++) { if (priv->nid == cipher_info_table[i].nid) { priv->setup.alg = cipher_info_table[i].alg; @@ -293,11 +369,34 @@ static int uadk_prov_cipher_init(struct cipher_priv_ctx *priv, } }
- if (i == cipher_counts) { + if (unlikely(i == cipher_counts)) { fprintf(stderr, "failed to setup the private ctx.\n"); return UADK_E_FAIL; }
+ return UADK_E_SUCCESS; +} + +static int uadk_prov_cipher_init(struct cipher_priv_ctx *priv, + const unsigned char *key, size_t keylen, + const unsigned char *iv, size_t ivlen) +{ + int ret; + + if (ivlen > IV_LEN || keylen > MAX_KEY_LEN) { + fprintf(stderr, "invalid keylen or ivlen.\n"); + return UADK_E_FAIL; + } + + if (iv) { + memcpy(priv->iv, iv, ivlen); + priv->iv_set = 1; + } + + ret = uadk_get_cipher_info(priv); + if (unlikely(!ret)) + return UADK_E_FAIL; + if (key) { memcpy(priv->key, key, keylen); priv->key_set = 1; @@ -361,6 +460,9 @@ static void uadk_cipher_update_priv_ctx(struct cipher_priv_ctx *priv) switch (priv->setup.mode) { case WD_CIPHER_CFB: case WD_CIPHER_CBC: + case WD_CIPHER_CBC_CS1: + case WD_CIPHER_CBC_CS2: + case WD_CIPHER_CBC_CS3: if (priv->req.op_type == WD_CIPHER_ENCRYPTION) memcpy(priv->iv, priv->req.dst + offset, iv_bytes); else @@ -1020,6 +1122,7 @@ static const OSSL_PARAM uadk_prov_settable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL), + OSSL_PARAM_utf8_string(OSSL_CIPHER_PARAM_CTS_MODE, NULL, 0), OSSL_PARAM_END };
@@ -1077,6 +1180,28 @@ static int uadk_prov_cipher_set_ctx_params(void *vctx, const OSSL_PARAM params[] } }
+ p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_CTS_MODE); + if (p != NULL) { + int id; + char *ptr; + + if (p->data_type != OSSL_PARAM_UTF8_STRING) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return UADK_E_FAIL; + } + + id = ossl_cipher_cbc_cts_mode_name2id(p->data); + if (id < 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return UADK_E_FAIL; + } + + priv->cts_mode = (unsigned int)id; + priv->setup.mode = priv->cts_mode; + strncpy(priv->alg_name, cts_modes[id - WD_CIPHER_CBC_CS1].uadk_alg_name, + ALG_NAME_SIZE - 1); + } + return UADK_E_SUCCESS; }
@@ -1115,6 +1240,15 @@ static int uadk_prov_cipher_get_ctx_params(void *vctx, OSSL_PARAM params[]) ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return UADK_E_FAIL; } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CTS_MODE); + if (p != NULL) { + const char *name = ossl_cipher_cbc_cts_mode_id2name(priv->cts_mode); + + if (name == NULL || !OSSL_PARAM_set_utf8_string(p, name)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return UADK_E_FAIL; + } + } return UADK_E_SUCCESS; }
@@ -1124,6 +1258,7 @@ static const OSSL_PARAM uadk_prov_default_ctx_params[] = { OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_CIPHER_PARAM_CTS_MODE, NULL, 0), OSSL_PARAM_END };
@@ -1214,6 +1349,7 @@ static void *uadk_##nm##_newctx(void *provctx) \ ctx->keylen = key_len; \ ctx->ivlen = iv_len; \ ctx->nid = e_nid; \ + ctx->cts_mode = WD_CIPHER_CBC_CS1; \ ctx->sw_ctx = EVP_CIPHER_CTX_new(); \ if (ctx->sw_ctx == NULL) \ fprintf(stderr, "EVP_CIPHER_CTX_new failed.\n"); \ @@ -1255,29 +1391,32 @@ const OSSL_DISPATCH uadk_##nm##_functions[] = { \ { 0, NULL } \ }
-UADK_CIPHER_DESCR(aes_128_cbc, 16, 16, 16, 0, NID_aes_128_cbc, cbc(aes), EVP_CIPH_CBC_MODE, block); -UADK_CIPHER_DESCR(aes_192_cbc, 16, 24, 16, 0, NID_aes_192_cbc, cbc(aes), EVP_CIPH_CBC_MODE, block); -UADK_CIPHER_DESCR(aes_256_cbc, 16, 32, 16, 0, NID_aes_256_cbc, cbc(aes), EVP_CIPH_CBC_MODE, block); -UADK_CIPHER_DESCR(aes_128_ecb, 16, 16, 0, 0, NID_aes_128_ecb, ecb(aes), EVP_CIPH_ECB_MODE, block); -UADK_CIPHER_DESCR(aes_192_ecb, 16, 24, 0, 0, NID_aes_192_ecb, ecb(aes), EVP_CIPH_ECB_MODE, block); -UADK_CIPHER_DESCR(aes_256_ecb, 16, 32, 0, 0, NID_aes_256_ecb, ecb(aes), EVP_CIPH_ECB_MODE, block); -UADK_CIPHER_DESCR(aes_128_xts, 1, 32, 16, PROV_CIPHER_FLAG_CUSTOM_IV, NID_aes_128_xts, xts(aes), EVP_CIPH_XTS_MODE, stream); -UADK_CIPHER_DESCR(aes_256_xts, 1, 64, 16, PROV_CIPHER_FLAG_CUSTOM_IV, NID_aes_256_xts, xts(aes), EVP_CIPH_XTS_MODE, stream); -UADK_CIPHER_DESCR(sm4_cbc, 16, 16, 16, 0, NID_sm4_cbc, cbc(sm4), EVP_CIPH_CBC_MODE, block); -UADK_CIPHER_DESCR(sm4_ecb, 16, 16, 0, 0, NID_sm4_ecb, ecb(sm4), EVP_CIPH_ECB_MODE, block); -UADK_CIPHER_DESCR(des_ede3_cbc, 8, 24, 8, 0, NID_des_ede3_cbc, cbc(des), EVP_CIPH_CBC_MODE, block); -UADK_CIPHER_DESCR(des_ede3_ecb, 8, 24, 0, 0, NID_des_ede3_ecb, ecb(des), EVP_CIPH_ECB_MODE, block); +UADK_CIPHER_DESCR(aes_128_cbc, 16, 16, 16, 0, ID_aes_128_cbc, cbc(aes), EVP_CIPH_CBC_MODE, block); +UADK_CIPHER_DESCR(aes_192_cbc, 16, 24, 16, 0, ID_aes_192_cbc, cbc(aes), EVP_CIPH_CBC_MODE, block); +UADK_CIPHER_DESCR(aes_256_cbc, 16, 32, 16, 0, ID_aes_256_cbc, cbc(aes), EVP_CIPH_CBC_MODE, block); +UADK_CIPHER_DESCR(aes_128_cts, 1, 16, 16, 0, ID_aes_128_cts, cbc-cs1(aes), EVP_CIPH_CBC_MODE, stream); +UADK_CIPHER_DESCR(aes_192_cts, 1, 24, 16, 0, ID_aes_192_cts, cbc-cs1(aes), EVP_CIPH_CBC_MODE, stream); +UADK_CIPHER_DESCR(aes_256_cts, 1, 32, 16, 0, ID_aes_256_cts, cbc-cs1(aes), EVP_CIPH_CBC_MODE, stream); +UADK_CIPHER_DESCR(aes_128_ecb, 16, 16, 0, 0, ID_aes_128_ecb, ecb(aes), EVP_CIPH_ECB_MODE, block); +UADK_CIPHER_DESCR(aes_192_ecb, 16, 24, 0, 0, ID_aes_192_ecb, ecb(aes), EVP_CIPH_ECB_MODE, block); +UADK_CIPHER_DESCR(aes_256_ecb, 16, 32, 0, 0, ID_aes_256_ecb, ecb(aes), EVP_CIPH_ECB_MODE, block); +UADK_CIPHER_DESCR(aes_128_xts, 1, 32, 16, PROV_CIPHER_FLAG_CUSTOM_IV, ID_aes_128_xts, xts(aes), EVP_CIPH_XTS_MODE, stream); +UADK_CIPHER_DESCR(aes_256_xts, 1, 64, 16, PROV_CIPHER_FLAG_CUSTOM_IV, ID_aes_256_xts, xts(aes), EVP_CIPH_XTS_MODE, stream); +UADK_CIPHER_DESCR(sm4_cbc, 16, 16, 16, 0, ID_sm4_cbc, cbc(sm4), EVP_CIPH_CBC_MODE, block); +UADK_CIPHER_DESCR(sm4_ecb, 16, 16, 0, 0, ID_sm4_ecb, ecb(sm4), EVP_CIPH_ECB_MODE, block); +UADK_CIPHER_DESCR(des_ede3_cbc, 8, 24, 8, 0, ID_des_ede3_cbc, cbc(des), EVP_CIPH_CBC_MODE, block); +UADK_CIPHER_DESCR(des_ede3_ecb, 8, 24, 0, 0, ID_des_ede3_ecb, ecb(des), EVP_CIPH_ECB_MODE, block);
/* v3 */ -UADK_CIPHER_DESCR(aes_128_ctr, 1, 16, 16, 0, NID_aes_128_ctr, ctr(aes), EVP_CIPH_CTR_MODE, stream); -UADK_CIPHER_DESCR(aes_192_ctr, 1, 24, 16, 0, NID_aes_192_ctr, ctr(aes), EVP_CIPH_CTR_MODE, stream); -UADK_CIPHER_DESCR(aes_256_ctr, 1, 32, 16, 0, NID_aes_256_ctr, ctr(aes), EVP_CIPH_CTR_MODE, stream); -UADK_CIPHER_DESCR(aes_128_ofb128, 1, 16, 16, 0, NID_aes_128_ofb128, ofb(aes), EVP_CIPH_OFB_MODE, stream); -UADK_CIPHER_DESCR(aes_192_ofb128, 1, 24, 16, 0, NID_aes_192_ofb128, ofb(aes), EVP_CIPH_OFB_MODE, stream); -UADK_CIPHER_DESCR(aes_256_ofb128, 1, 32, 16, 0, NID_aes_256_ofb128, ofb(aes), EVP_CIPH_OFB_MODE, stream); -UADK_CIPHER_DESCR(aes_128_cfb128, 1, 16, 16, 0, NID_aes_128_cfb128, cfb(aes), EVP_CIPH_CFB_MODE, stream); -UADK_CIPHER_DESCR(aes_192_cfb128, 1, 24, 16, 0, NID_aes_192_cfb128, cfb(aes), EVP_CIPH_CFB_MODE, stream); -UADK_CIPHER_DESCR(aes_256_cfb128, 1, 32, 16, 0, NID_aes_256_cfb128, cfb(aes), EVP_CIPH_CFB_MODE, stream); -UADK_CIPHER_DESCR(sm4_ofb128, 1, 16, 16, 0, NID_sm4_ofb128, ofb(sm4), EVP_CIPH_OFB_MODE, stream); -UADK_CIPHER_DESCR(sm4_cfb128, 1, 16, 16, 0, NID_sm4_cfb128, cfb(sm4), EVP_CIPH_CFB_MODE, stream); -UADK_CIPHER_DESCR(sm4_ctr, 1, 16, 16, 0, NID_sm4_ctr, ctr(sm4), EVP_CIPH_CTR_MODE, stream); +UADK_CIPHER_DESCR(aes_128_ctr, 1, 16, 16, 0, ID_aes_128_ctr, ctr(aes), EVP_CIPH_CTR_MODE, stream); +UADK_CIPHER_DESCR(aes_192_ctr, 1, 24, 16, 0, ID_aes_192_ctr, ctr(aes), EVP_CIPH_CTR_MODE, stream); +UADK_CIPHER_DESCR(aes_256_ctr, 1, 32, 16, 0, ID_aes_256_ctr, ctr(aes), EVP_CIPH_CTR_MODE, stream); +UADK_CIPHER_DESCR(aes_128_ofb128, 1, 16, 16, 0, ID_aes_128_ofb128, ofb(aes), EVP_CIPH_OFB_MODE, stream); +UADK_CIPHER_DESCR(aes_192_ofb128, 1, 24, 16, 0, ID_aes_192_ofb128, ofb(aes), EVP_CIPH_OFB_MODE, stream); +UADK_CIPHER_DESCR(aes_256_ofb128, 1, 32, 16, 0, ID_aes_256_ofb128, ofb(aes), EVP_CIPH_OFB_MODE, stream); +UADK_CIPHER_DESCR(aes_128_cfb128, 1, 16, 16, 0, ID_aes_128_cfb128, cfb(aes), EVP_CIPH_CFB_MODE, stream); +UADK_CIPHER_DESCR(aes_192_cfb128, 1, 24, 16, 0, ID_aes_192_cfb128, cfb(aes), EVP_CIPH_CFB_MODE, stream); +UADK_CIPHER_DESCR(aes_256_cfb128, 1, 32, 16, 0, ID_aes_256_cfb128, cfb(aes), EVP_CIPH_CFB_MODE, stream); +UADK_CIPHER_DESCR(sm4_ofb128, 1, 16, 16, 0, ID_sm4_ofb128, ofb(sm4), EVP_CIPH_OFB_MODE, stream); +UADK_CIPHER_DESCR(sm4_cfb128, 1, 16, 16, 0, ID_sm4_cfb128, cfb(sm4), EVP_CIPH_CFB_MODE, stream); +UADK_CIPHER_DESCR(sm4_ctr, 1, 16, 16, 0, ID_sm4_ctr, ctr(sm4), EVP_CIPH_CTR_MODE, stream); diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c index 05a1b9f..d4adb20 100644 --- a/src/uadk_prov_init.c +++ b/src/uadk_prov_init.c @@ -79,6 +79,12 @@ const OSSL_ALGORITHM uadk_prov_ciphers[] = { uadk_aes_192_cbc_functions, "uadk_provider aes-192-cbc" }, { "AES-256-CBC", UADK_DEFAULT_PROPERTIES, uadk_aes_256_cbc_functions, "uadk_provider aes-256-cbc" }, + { "AES-128-CBC-CTS", UADK_DEFAULT_PROPERTIES, + uadk_aes_128_cts_functions, "uadk_provider aes-128-cbc-cts" }, + { "AES-192-CBC-CTS", UADK_DEFAULT_PROPERTIES, + uadk_aes_192_cts_functions, "uadk_provider aes-192-cbc-cts" }, + { "AES-256-CBC-CTS", UADK_DEFAULT_PROPERTIES, + uadk_aes_256_cts_functions, "uadk_provider aes-256-cbc-cts" }, { "AES-128-ECB", UADK_DEFAULT_PROPERTIES, uadk_aes_128_ecb_functions, "uadk_provider aes-128-ecb" }, { "AES-192-ECB", UADK_DEFAULT_PROPERTIES,
From: Chenghai Huang huangchenghai2@huawei.com
On openssl version 3.0, the pad function is not enabled in the default scenario. After the data encrypted by pad is decrypted, the result is inconsistent with the original data.
Therefore, pad processing needs to be performed through soft calculation to ensure that the results are correct.
Signed-off-by: Chenghai Huang huangchenghai2@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_prov_cipher.c | 121 +++++++++++++++++++++++------------------ 1 file changed, 67 insertions(+), 54 deletions(-)
diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c index 623347e..44ea74b 100644 --- a/src/uadk_prov_cipher.c +++ b/src/uadk_prov_cipher.c @@ -332,6 +332,22 @@ static int uadk_prov_cipher_soft_work(struct cipher_priv_ctx *priv, unsigned cha return UADK_E_SUCCESS; }
+static int uadk_prov_cipher_soft_final(struct cipher_priv_ctx *priv, unsigned char *out, + size_t *outl) +{ + size_t sw_final_len = 0; + + if (priv->sw_cipher == NULL) + return UADK_E_FAIL; + + if (!EVP_CipherFinal_ex(priv->sw_ctx, out, &sw_final_len)) { + fprintf(stderr, "EVP_CipherFinal_ex sw_ctx failed.\n"); + return UADK_E_FAIL; + } + *outl = sw_final_len; + return UADK_E_SUCCESS; +} + static void uadk_prov_cipher_dev_init(struct cipher_priv_ctx *priv);
static int uadk_cipher_poll(void *ctx) @@ -907,50 +923,45 @@ static int uadk_prov_cipher_cipher(void *vctx, unsigned char *out, size_t *outl, return UADK_E_SUCCESS; }
-static int uadk_prov_cipher_block_final(void *vctx, unsigned char *out, - size_t *outl, size_t outsize) +static int uadk_prov_cipher_block_encrypto(struct cipher_priv_ctx *priv, + unsigned char *out, size_t *outl, size_t outsize) { - struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; size_t blksz = priv->blksize; - int sw_final_len = 0; int ret;
- if (!vctx || !out || !outl) + if (priv->pad) { + ossl_cipher_padblock(priv->buf, &priv->bufsz, blksz); + } else if (priv->bufsz == 0) { + *outl = 0; + return UADK_E_SUCCESS; + } else if (priv->bufsz != blksz) { + ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH); return UADK_E_FAIL; + }
- if (priv->sw_cipher && - priv->switch_flag == UADK_DO_SOFT) { - goto do_soft; + if (outsize < blksz) { + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + return UADK_E_FAIL; }
- if (priv->enc) { - if (priv->pad) { - ossl_cipher_padblock(priv->buf, &priv->bufsz, blksz); - } else if (priv->bufsz == 0) { - *outl = 0; - return UADK_E_SUCCESS; - } else if (priv->bufsz != blksz) { - ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH); - return UADK_E_FAIL; - } + ret = uadk_prov_hw_cipher(priv, out, outl, outsize, priv->buf, blksz); + if (ret != UADK_E_SUCCESS) { + fprintf(stderr, "do hw ciphers failed, switch to soft ciphers.\n"); + return uadk_prov_cipher_soft_final(priv, out, outl); + }
- if (outsize < blksz) { - ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); - return UADK_E_FAIL; - } + *outl = blksz;
- ret = uadk_prov_hw_cipher(priv, out, outl, outsize, priv->buf, blksz); - if (ret != UADK_E_SUCCESS) { - fprintf(stderr, "do hw ciphers failed.\n"); - if (priv->sw_cipher) - goto do_soft; - return ret; - } - *outl = blksz; - return UADK_E_SUCCESS; - } + return UADK_E_SUCCESS; +} + +static int uadk_prov_cipher_block_decrypto(struct cipher_priv_ctx *priv, + unsigned char *out, size_t *outl, size_t outsize) +{ + size_t blksz = priv->blksize; + int ret;
- /* dec should handle last blk since pad */ + /* Dec should handle last blk since pad */ if (priv->bufsz != blksz) { if (priv->bufsz == 0 && !priv->pad) { *outl = 0; @@ -961,11 +972,9 @@ static int uadk_prov_cipher_block_final(void *vctx, unsigned char *out, }
ret = uadk_prov_hw_cipher(priv, priv->buf, outl, outsize, priv->buf, blksz); - if (ret != 1) { - fprintf(stderr, "do hw ciphers failed.\n"); - if (priv->sw_cipher) - goto do_soft; - return ret; + if (ret != UADK_E_SUCCESS) { + fprintf(stderr, "do hw ciphers failed, switch to soft ciphers.\n"); + return uadk_prov_cipher_soft_final(priv, out, outl); }
if (priv->pad && !ossl_cipher_unpadblock(priv->buf, &priv->bufsz, blksz)) { @@ -983,14 +992,26 @@ static int uadk_prov_cipher_block_final(void *vctx, unsigned char *out, priv->bufsz = 0;
return UADK_E_SUCCESS; +}
-do_soft: - if (!EVP_CipherFinal_ex(priv->sw_ctx, out, &sw_final_len)) { - fprintf(stderr, "EVP_CipherFinal_ex sw_ctx failed.\n"); +static int uadk_prov_cipher_block_final(void *vctx, unsigned char *out, + size_t *outl, size_t outsize) +{ + struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; + int ret; + + if (!vctx || !out || !outl) return UADK_E_FAIL; - } - *outl = sw_final_len; - return UADK_E_SUCCESS; + + if (priv->switch_flag == UADK_DO_SOFT) + return uadk_prov_cipher_soft_final(priv, out, outl); + + if (priv->enc) + ret = uadk_prov_cipher_block_encrypto(priv, out, outl, outsize); + else + ret = uadk_prov_cipher_block_decrypto(priv, out, outl, outsize); + + return ret; }
static int uadk_prov_cipher_block_update(void *vctx, unsigned char *out, @@ -1069,20 +1090,12 @@ static int uadk_prov_cipher_stream_final(void *vctx, unsigned char *out, size_t *outl, size_t outsize) { struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; - int sw_final_len = 0;
if (!vctx || !out || !outl) return UADK_E_FAIL;
- if (priv->sw_cipher && - priv->switch_flag == UADK_DO_SOFT) { - if (!EVP_CipherFinal_ex(priv->sw_ctx, out, &sw_final_len)) { - fprintf(stderr, "EVP_CipherFinal_ex sw_ctx failed.\n"); - return UADK_E_FAIL; - } - *outl = sw_final_len; - return UADK_E_SUCCESS; - } + if (priv->switch_flag == UADK_DO_SOFT) + return uadk_prov_cipher_soft_final(priv, out, outl);
*outl = 0; return UADK_E_SUCCESS;
From: Wenkai Lin linwenkai6@hisilicon.com
The IV has been updated by the uadk, the uadk engine does not need update it and use the right out_bytes to determine whether to update the IV.
Signed-off-by: Wenkai Lin linwenkai6@hisilicon.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_cipher.c | 112 ++++++++++----------------------------- src/uadk_prov_cipher.c | 116 ++++++++++------------------------------- 2 files changed, 56 insertions(+), 172 deletions(-)
diff --git a/src/uadk_cipher.c b/src/uadk_cipher.c index 44b0aa0..1cfbc0e 100644 --- a/src/uadk_cipher.c +++ b/src/uadk_cipher.c @@ -33,9 +33,6 @@ #define CTX_ASYNC_ENC 2 #define CTX_ASYNC_DEC 3 #define CTX_NUM 4 -#define CTR_128BIT_COUNTER 16 -#define CTR_MODE_LEN_SHIFT 4 -#define BYTE_BITS 8 #define IV_LEN 16 #define ENV_ENABLED 1 #define MAX_KEY_LEN 64 @@ -74,7 +71,6 @@ struct cipher_info { int nid; enum wd_cipher_alg alg; enum wd_cipher_mode mode; - __u32 out_bytes; };
static EVP_CIPHER *uadk_aes_128_cbc; @@ -130,30 +126,30 @@ static struct sw_cipher_t sec_ciphers_sw_table[] = { };
static struct cipher_info cipher_info_table[] = { - { NID_aes_128_ecb, WD_CIPHER_AES, WD_CIPHER_ECB, 16}, - { NID_aes_192_ecb, WD_CIPHER_AES, WD_CIPHER_ECB, 16}, - { NID_aes_256_ecb, WD_CIPHER_AES, WD_CIPHER_ECB, 16}, - { NID_aes_128_cbc, WD_CIPHER_AES, WD_CIPHER_CBC, 16}, - { NID_aes_192_cbc, WD_CIPHER_AES, WD_CIPHER_CBC, 64}, - { NID_aes_256_cbc, WD_CIPHER_AES, WD_CIPHER_CBC, 64}, - { NID_aes_128_xts, WD_CIPHER_AES, WD_CIPHER_XTS, 32}, - { NID_aes_256_xts, WD_CIPHER_AES, WD_CIPHER_XTS, 512}, - { NID_sm4_cbc, WD_CIPHER_SM4, WD_CIPHER_CBC, 16}, - { NID_des_ede3_cbc, WD_CIPHER_3DES, WD_CIPHER_CBC, 16}, - { NID_des_ede3_ecb, WD_CIPHER_3DES, WD_CIPHER_ECB, 16}, - { NID_aes_128_ctr, WD_CIPHER_AES, WD_CIPHER_CTR, 64}, - { NID_aes_192_ctr, WD_CIPHER_AES, WD_CIPHER_CTR, 64}, - { NID_aes_256_ctr, WD_CIPHER_AES, WD_CIPHER_CTR, 64}, - { NID_aes_128_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB, 16}, - { NID_aes_192_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB, 16}, - { NID_aes_256_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB, 16}, - { NID_aes_128_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB, 16}, - { NID_aes_192_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB, 16}, - { NID_aes_256_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB, 16}, - { NID_sm4_ofb128, WD_CIPHER_SM4, WD_CIPHER_OFB, 16}, - { NID_sm4_cfb128, WD_CIPHER_SM4, WD_CIPHER_CFB, 16}, - { NID_sm4_ecb, WD_CIPHER_SM4, WD_CIPHER_ECB, 16}, - { NID_sm4_ctr, WD_CIPHER_SM4, WD_CIPHER_CTR, 16}, + { NID_aes_128_ecb, WD_CIPHER_AES, WD_CIPHER_ECB}, + { NID_aes_192_ecb, WD_CIPHER_AES, WD_CIPHER_ECB}, + { NID_aes_256_ecb, WD_CIPHER_AES, WD_CIPHER_ECB}, + { NID_aes_128_cbc, WD_CIPHER_AES, WD_CIPHER_CBC}, + { NID_aes_192_cbc, WD_CIPHER_AES, WD_CIPHER_CBC}, + { NID_aes_256_cbc, WD_CIPHER_AES, WD_CIPHER_CBC}, + { NID_aes_128_xts, WD_CIPHER_AES, WD_CIPHER_XTS}, + { NID_aes_256_xts, WD_CIPHER_AES, WD_CIPHER_XTS}, + { NID_sm4_cbc, WD_CIPHER_SM4, WD_CIPHER_CBC}, + { NID_des_ede3_cbc, WD_CIPHER_3DES, WD_CIPHER_CBC}, + { NID_des_ede3_ecb, WD_CIPHER_3DES, WD_CIPHER_ECB}, + { NID_aes_128_ctr, WD_CIPHER_AES, WD_CIPHER_CTR}, + { NID_aes_192_ctr, WD_CIPHER_AES, WD_CIPHER_CTR}, + { NID_aes_256_ctr, WD_CIPHER_AES, WD_CIPHER_CTR}, + { NID_aes_128_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB}, + { NID_aes_192_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB}, + { NID_aes_256_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB}, + { NID_aes_128_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB}, + { NID_aes_192_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB}, + { NID_aes_256_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB}, + { NID_sm4_ofb128, WD_CIPHER_SM4, WD_CIPHER_OFB}, + { NID_sm4_cfb128, WD_CIPHER_SM4, WD_CIPHER_CFB}, + { NID_sm4_ecb, WD_CIPHER_SM4, WD_CIPHER_ECB}, + { NID_sm4_ctr, WD_CIPHER_SM4, WD_CIPHER_CTR}, };
static const EVP_CIPHER *sec_ciphers_get_cipher_sw_impl(int n_id) @@ -484,11 +480,10 @@ err_unlock: }
static void cipher_priv_ctx_setup(struct cipher_priv_ctx *priv, - enum wd_cipher_alg alg, enum wd_cipher_mode mode, __u32 out_bytes) + enum wd_cipher_alg alg, enum wd_cipher_mode mode) { priv->setup.alg = alg; priv->setup.mode = mode; - priv->req.out_bytes = out_bytes; }
static int uadk_e_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, @@ -519,7 +514,7 @@ static int uadk_e_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, for (i = 0; i < cipher_counts; i++) { if (nid == cipher_info_table[i].nid) { cipher_priv_ctx_setup(priv, cipher_info_table[i].alg, - cipher_info_table[i].mode, cipher_info_table[i].out_bytes); + cipher_info_table[i].mode); break; } } @@ -576,57 +571,6 @@ static void *uadk_e_cipher_cb(struct wd_cipher_req *req, void *data) return NULL; }
-/* Increment counter (128-bit int) by c */ -static void ctr_iv_inc(uint8_t *counter, __u32 c) -{ - uint32_t n = CTR_128BIT_COUNTER; - uint8_t *counter1 = counter; - __u32 c_value = c; - - /* - * Since the counter has been increased 1 by the hardware, - * so the c need to decrease 1. - */ - c_value -= 1; - do { - --n; - c_value += counter1[n]; - counter1[n] = (uint8_t)c_value; - c_value >>= BYTE_BITS; - } while (n); -} - -static void uadk_cipher_update_priv_ctx(struct cipher_priv_ctx *priv) -{ - __u16 iv_bytes = priv->req.iv_bytes; - int offset = priv->req.in_bytes - iv_bytes; - unsigned char K[IV_LEN] = {0}; - __u32 i; - - switch (priv->setup.mode) { - case WD_CIPHER_CFB: - case WD_CIPHER_CBC: - if (priv->req.op_type == WD_CIPHER_ENCRYPTION) - memcpy(priv->iv, priv->req.dst + offset, iv_bytes); - else - memcpy(priv->iv, priv->req.src + offset, iv_bytes); - - break; - case WD_CIPHER_OFB: - for (i = 0; i < IV_LEN; i++) { - K[i] = *((unsigned char *)priv->req.src + offset + i) ^ - *((unsigned char *)priv->req.dst + offset + i); - } - memcpy(priv->iv, K, iv_bytes); - break; - case WD_CIPHER_CTR: - ctr_iv_inc(priv->iv, priv->req.in_bytes >> CTR_MODE_LEN_SHIFT); - break; - default: - break; - } -} - static int do_cipher_sync(struct cipher_priv_ctx *priv) { int ret; @@ -742,7 +686,7 @@ static void uadk_e_ctx_init(EVP_CIPHER_CTX *ctx, struct cipher_priv_ctx *priv) for (i = 0; i < cipher_counts; i++) { if (nid == cipher_info_table[i].nid) { cipher_priv_ctx_setup(priv, cipher_info_table[i].alg, - cipher_info_table[i].mode, cipher_info_table[i].out_bytes); + cipher_info_table[i].mode); break; } } @@ -782,6 +726,7 @@ static int uadk_e_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
priv->req.src = (unsigned char *)in; priv->req.in_bytes = inlen; + priv->req.out_bytes = inlen; priv->req.dst = out; priv->req.out_buf_bytes = inlen;
@@ -813,7 +758,6 @@ static int uadk_e_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (!ret) goto out_notify; } - uadk_cipher_update_priv_ctx(priv);
return 1;
diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c index 44ea74b..7847c12 100644 --- a/src/uadk_prov_cipher.c +++ b/src/uadk_prov_cipher.c @@ -37,9 +37,6 @@ #define CTX_ASYNC_ENC 2 #define CTX_ASYNC_DEC 3 #define CTX_NUM 4 -#define CTR_128BIT_COUNTER 16 -#define CTR_MODE_LEN_SHIFT 4 -#define BYTE_BITS 8 #define IV_LEN 16 #define ENV_ENABLED 1 #define MAX_KEY_LEN 64 @@ -140,37 +137,36 @@ struct cipher_info { int nid; enum wd_cipher_alg alg; enum wd_cipher_mode mode; - __u32 out_bytes; };
static struct cipher_info cipher_info_table[] = { - { ID_aes_128_ecb, WD_CIPHER_AES, WD_CIPHER_ECB, 16}, - { ID_aes_192_ecb, WD_CIPHER_AES, WD_CIPHER_ECB, 16}, - { ID_aes_256_ecb, WD_CIPHER_AES, WD_CIPHER_ECB, 16}, - { ID_aes_128_cbc, WD_CIPHER_AES, WD_CIPHER_CBC, 16}, - { ID_aes_192_cbc, WD_CIPHER_AES, WD_CIPHER_CBC, 64}, - { ID_aes_256_cbc, WD_CIPHER_AES, WD_CIPHER_CBC, 64}, - { ID_aes_128_cts, WD_CIPHER_AES, WD_CIPHER_CBC_CS1, 16}, - { ID_aes_192_cts, WD_CIPHER_AES, WD_CIPHER_CBC_CS1, 16}, - { ID_aes_256_cts, WD_CIPHER_AES, WD_CIPHER_CBC_CS1, 64}, - { ID_aes_128_xts, WD_CIPHER_AES, WD_CIPHER_XTS, 32}, - { ID_aes_256_xts, WD_CIPHER_AES, WD_CIPHER_XTS, 512}, - { ID_aes_128_ctr, WD_CIPHER_AES, WD_CIPHER_CTR, 64}, - { ID_aes_192_ctr, WD_CIPHER_AES, WD_CIPHER_CTR, 64}, - { ID_aes_256_ctr, WD_CIPHER_AES, WD_CIPHER_CTR, 64}, - { ID_aes_128_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB, 16}, - { ID_aes_192_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB, 16}, - { ID_aes_256_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB, 16}, - { ID_aes_128_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB, 16}, - { ID_aes_192_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB, 16}, - { ID_aes_256_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB, 16}, - { ID_sm4_cbc, WD_CIPHER_SM4, WD_CIPHER_CBC, 16}, - { ID_sm4_ofb128, WD_CIPHER_SM4, WD_CIPHER_OFB, 16}, - { ID_sm4_cfb128, WD_CIPHER_SM4, WD_CIPHER_CFB, 16}, - { ID_sm4_ecb, WD_CIPHER_SM4, WD_CIPHER_ECB, 16}, - { ID_sm4_ctr, WD_CIPHER_SM4, WD_CIPHER_CTR, 16}, - { ID_des_ede3_cbc, WD_CIPHER_3DES, WD_CIPHER_CBC, 16}, - { ID_des_ede3_ecb, WD_CIPHER_3DES, WD_CIPHER_ECB, 16}, + { ID_aes_128_ecb, WD_CIPHER_AES, WD_CIPHER_ECB}, + { ID_aes_192_ecb, WD_CIPHER_AES, WD_CIPHER_ECB}, + { ID_aes_256_ecb, WD_CIPHER_AES, WD_CIPHER_ECB}, + { ID_aes_128_cbc, WD_CIPHER_AES, WD_CIPHER_CBC}, + { ID_aes_192_cbc, WD_CIPHER_AES, WD_CIPHER_CBC}, + { ID_aes_256_cbc, WD_CIPHER_AES, WD_CIPHER_CBC}, + { ID_aes_128_cts, WD_CIPHER_AES, WD_CIPHER_CBC_CS1}, + { ID_aes_192_cts, WD_CIPHER_AES, WD_CIPHER_CBC_CS1}, + { ID_aes_256_cts, WD_CIPHER_AES, WD_CIPHER_CBC_CS1}, + { ID_aes_128_xts, WD_CIPHER_AES, WD_CIPHER_XTS}, + { ID_aes_256_xts, WD_CIPHER_AES, WD_CIPHER_XTS}, + { ID_aes_128_ctr, WD_CIPHER_AES, WD_CIPHER_CTR}, + { ID_aes_192_ctr, WD_CIPHER_AES, WD_CIPHER_CTR}, + { ID_aes_256_ctr, WD_CIPHER_AES, WD_CIPHER_CTR}, + { ID_aes_128_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB}, + { ID_aes_192_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB}, + { ID_aes_256_ofb128, WD_CIPHER_AES, WD_CIPHER_OFB}, + { ID_aes_128_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB}, + { ID_aes_192_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB}, + { ID_aes_256_cfb128, WD_CIPHER_AES, WD_CIPHER_CFB}, + { ID_sm4_cbc, WD_CIPHER_SM4, WD_CIPHER_CBC}, + { ID_sm4_ofb128, WD_CIPHER_SM4, WD_CIPHER_OFB}, + { ID_sm4_cfb128, WD_CIPHER_SM4, WD_CIPHER_CFB}, + { ID_sm4_ecb, WD_CIPHER_SM4, WD_CIPHER_ECB}, + { ID_sm4_ctr, WD_CIPHER_SM4, WD_CIPHER_CTR}, + { ID_des_ede3_cbc, WD_CIPHER_3DES, WD_CIPHER_CBC}, + { ID_des_ede3_ecb, WD_CIPHER_3DES, WD_CIPHER_ECB}, };
struct cts_mode_name2id_st { @@ -380,7 +376,6 @@ static int uadk_get_cipher_info(struct cipher_priv_ctx *priv) if (priv->nid == cipher_info_table[i].nid) { priv->setup.alg = cipher_info_table[i].alg; priv->setup.mode = cipher_info_table[i].mode; - priv->req.out_bytes = cipher_info_table[i].out_bytes; break; } } @@ -446,60 +441,6 @@ static void async_cb(struct wd_cipher_req *req, void *data) } }
-/* Increment counter (128-bit int) by c */ -static void ctr_iv_inc(uint8_t *counter, __u32 c) -{ - uint32_t n = CTR_128BIT_COUNTER; - uint8_t *counter1 = counter; - __u32 c_value = c; - - /* - * Since the counter has been increased 1 by the hardware, - * so the c need to decrease 1. - */ - c_value -= 1; - do { - --n; - c_value += counter1[n]; - counter1[n] = (uint8_t)c_value; - c_value >>= BYTE_BITS; - } while (n); -} - -static void uadk_cipher_update_priv_ctx(struct cipher_priv_ctx *priv) -{ - __u16 iv_bytes = priv->req.iv_bytes; - int offset = priv->req.in_bytes - iv_bytes; - unsigned char K[IV_LEN] = {0}; - int i; - - switch (priv->setup.mode) { - case WD_CIPHER_CFB: - case WD_CIPHER_CBC: - case WD_CIPHER_CBC_CS1: - case WD_CIPHER_CBC_CS2: - case WD_CIPHER_CBC_CS3: - if (priv->req.op_type == WD_CIPHER_ENCRYPTION) - memcpy(priv->iv, priv->req.dst + offset, iv_bytes); - else - memcpy(priv->iv, priv->req.src + offset, iv_bytes); - - break; - case WD_CIPHER_OFB: - for (i = 0; i < IV_LEN; i++) { - K[i] = *((unsigned char *)priv->req.src + offset + i) ^ - *((unsigned char *)priv->req.dst + offset + i); - } - memcpy(priv->iv, K, iv_bytes); - break; - case WD_CIPHER_CTR: - ctr_iv_inc(priv->iv, priv->req.in_bytes >> CTR_MODE_LEN_SHIFT); - break; - default: - break; - } -} - static int uadk_do_cipher_sync(struct cipher_priv_ctx *priv) { int ret; @@ -758,6 +699,7 @@ static int uadk_prov_hw_cipher(struct cipher_priv_ctx *priv, unsigned char *out, priv->switch_flag = UADK_DO_HW; priv->req.src = (unsigned char *)in; priv->req.in_bytes = inlen; + priv->req.out_bytes = inlen; priv->req.dst = out; priv->req.out_buf_bytes = inlen;
@@ -786,8 +728,6 @@ static int uadk_prov_hw_cipher(struct cipher_priv_ctx *priv, unsigned char *out, } }
- uadk_cipher_update_priv_ctx(priv); - return UADK_E_SUCCESS; }
Use UADK_PKEY_KEYMGMT_DESCR, UADK_PKEY_SIGNATURE_DESCR and UADK_PKEY_ASYM_CIPHER_DESCR macro to unify the definitions of RSA functions, reducing code duplication ratio.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com Signed-off-by: Qi Tao taoqi10@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_prov_pkey.h | 6 + src/uadk_prov_rsa.c | 449 +++++++++++-------------------------------- src/uadk_prov_sm2.c | 13 ++ 3 files changed, 134 insertions(+), 334 deletions(-)
diff --git a/src/uadk_prov_pkey.h b/src/uadk_prov_pkey.h index 105d9bb..a1805e6 100644 --- a/src/uadk_prov_pkey.h +++ b/src/uadk_prov_pkey.h @@ -259,6 +259,8 @@ static OSSL_FUNC_signature_sign_init_fn uadk_signature_##nm##_sign_init; \ static OSSL_FUNC_signature_verify_init_fn uadk_signature_##nm##_verify_init; \ static OSSL_FUNC_signature_sign_fn uadk_signature_##nm##_sign; \ static OSSL_FUNC_signature_verify_fn uadk_signature_##nm##_verify; \ +static OSSL_FUNC_signature_verify_recover_init_fn uadk_signature_##nm##_verify_recover_init; \ +static OSSL_FUNC_signature_verify_recover_fn uadk_signature_##nm##_verify_recover; \ static OSSL_FUNC_signature_digest_sign_init_fn uadk_signature_##nm##_digest_sign_init; \ static OSSL_FUNC_signature_digest_sign_update_fn uadk_signature_##nm##_digest_sign_update; \ static OSSL_FUNC_signature_digest_sign_final_fn uadk_signature_##nm##_digest_sign_final; \ @@ -301,6 +303,10 @@ const OSSL_DISPATCH uadk_##nm##_signature_functions[] = { \ { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))uadk_signature_##nm##_sign }, \ { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))uadk_signature_##nm##_verify_init }, \ { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))uadk_signature_##nm##_verify }, \ + { OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT, \ + (void (*)(void))uadk_signature_##nm##_verify_recover_init }, \ + { OSSL_FUNC_SIGNATURE_VERIFY_RECOVER, \ + (void (*)(void))uadk_signature_##nm##_verify_recover }, \ { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, \ (void (*)(void))uadk_signature_##nm##_digest_sign_init }, \ { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, \ diff --git a/src/uadk_prov_rsa.c b/src/uadk_prov_rsa.c index 03456fb..15f72eb 100644 --- a/src/uadk_prov_rsa.c +++ b/src/uadk_prov_rsa.c @@ -29,6 +29,7 @@ #include "uadk_async.h" #include "uadk.h" #include "uadk_prov.h" +#include "uadk_prov_pkey.h"
#define UN_SET 0 #define IS_SET 1 @@ -64,6 +65,10 @@ #define PRIME_CHECK_BIT_NUM 4 #define SOFT_SWITCH 0
+UADK_PKEY_KEYMGMT_DESCR(rsa, RSA); +UADK_PKEY_SIGNATURE_DESCR(rsa, RSA); +UADK_PKEY_ASYM_CIPHER_DESCR(rsa, RSA); + struct bignum_st { BN_ULONG *d; int top; @@ -234,117 +239,6 @@ struct rsa_st { int dirty_cnt; };
-typedef struct rsa_st RSA; - -/* EVP_SIGNATURE */ -struct evp_signature_st { - int name_id; - char *type_name; - const char *description; - OSSL_PROVIDER *prov; - CRYPTO_REF_COUNT refcnt; -# if OPENSSL_VERSION_NUMBER < 0x30200000 - CRYPTO_RWLOCK *lock; -# endif - OSSL_FUNC_signature_newctx_fn *newctx; - OSSL_FUNC_signature_sign_init_fn *sign_init; - OSSL_FUNC_signature_sign_fn *sign; - OSSL_FUNC_signature_verify_init_fn *verify_init; - OSSL_FUNC_signature_verify_fn *verify; - OSSL_FUNC_signature_verify_recover_init_fn *verify_recover_init; - OSSL_FUNC_signature_verify_recover_fn *verify_recover; - OSSL_FUNC_signature_digest_sign_init_fn *digest_sign_init; - OSSL_FUNC_signature_digest_sign_update_fn *digest_sign_update; - OSSL_FUNC_signature_digest_sign_final_fn *digest_sign_final; - OSSL_FUNC_signature_digest_sign_fn *digest_sign; - OSSL_FUNC_signature_digest_verify_init_fn *digest_verify_init; - OSSL_FUNC_signature_digest_verify_update_fn *digest_verify_update; - OSSL_FUNC_signature_digest_verify_final_fn *digest_verify_final; - OSSL_FUNC_signature_digest_verify_fn *digest_verify; - OSSL_FUNC_signature_freectx_fn *freectx; - OSSL_FUNC_signature_dupctx_fn *dupctx; - OSSL_FUNC_signature_get_ctx_params_fn *get_ctx_params; - OSSL_FUNC_signature_gettable_ctx_params_fn *gettable_ctx_params; - OSSL_FUNC_signature_set_ctx_params_fn *set_ctx_params; - OSSL_FUNC_signature_settable_ctx_params_fn *settable_ctx_params; - OSSL_FUNC_signature_get_ctx_md_params_fn *get_ctx_md_params; - OSSL_FUNC_signature_gettable_ctx_md_params_fn *gettable_ctx_md_params; - OSSL_FUNC_signature_set_ctx_md_params_fn *set_ctx_md_params; - OSSL_FUNC_signature_settable_ctx_md_params_fn *settable_ctx_md_params; -}; - -/* EVP_ASYM_CIPHER */ -struct evp_asym_cipher_st { - int name_id; - char *type_name; - const char *description; - OSSL_PROVIDER *prov; - CRYPTO_REF_COUNT refcnt; -# if OPENSSL_VERSION_NUMBER < 0x30200000 - CRYPTO_RWLOCK *lock; -#endif - OSSL_FUNC_asym_cipher_newctx_fn *newctx; - OSSL_FUNC_asym_cipher_encrypt_init_fn *encrypt_init; - OSSL_FUNC_asym_cipher_encrypt_fn *encrypt; - OSSL_FUNC_asym_cipher_decrypt_init_fn *decrypt_init; - OSSL_FUNC_asym_cipher_decrypt_fn *decrypt; - OSSL_FUNC_asym_cipher_freectx_fn *freectx; - OSSL_FUNC_asym_cipher_dupctx_fn *dupctx; - OSSL_FUNC_asym_cipher_get_ctx_params_fn *get_ctx_params; - OSSL_FUNC_asym_cipher_gettable_ctx_params_fn *gettable_ctx_params; - OSSL_FUNC_asym_cipher_set_ctx_params_fn *set_ctx_params; - OSSL_FUNC_asym_cipher_settable_ctx_params_fn *settable_ctx_params; -}; - -typedef struct{ - int id; /* libcrypto internal */ - int name_id; - char *type_name; - const char *description; - OSSL_PROVIDER *prov; - - CRYPTO_REF_COUNT refcnt; -# if OPENSSL_VERSION_NUMBER < 0x30200000 - CRYPTO_RWLOCK *lock; -# endif - - /* Constructor(s), destructor, information */ - OSSL_FUNC_keymgmt_new_fn *new_fun; - OSSL_FUNC_keymgmt_free_fn *free; - OSSL_FUNC_keymgmt_get_params_fn *get_params; - OSSL_FUNC_keymgmt_gettable_params_fn *gettable_params; - OSSL_FUNC_keymgmt_set_params_fn *set_params; - OSSL_FUNC_keymgmt_settable_params_fn *settable_params; - - /* Generation, a complex constructor */ - OSSL_FUNC_keymgmt_gen_init_fn *gen_init; - OSSL_FUNC_keymgmt_gen_set_template_fn *gen_set_template; - OSSL_FUNC_keymgmt_gen_set_params_fn *gen_set_params; - OSSL_FUNC_keymgmt_gen_settable_params_fn *gen_settable_params; - OSSL_FUNC_keymgmt_gen_fn *gen; - OSSL_FUNC_keymgmt_gen_cleanup_fn *gen_cleanup; - OSSL_FUNC_keymgmt_load_fn *load; - - /* Key object checking */ - OSSL_FUNC_keymgmt_query_operation_name_fn *query_operation_name; - OSSL_FUNC_keymgmt_has_fn *has; - OSSL_FUNC_keymgmt_validate_fn *validate; - OSSL_FUNC_keymgmt_match_fn *match; - - /* Import and export routines */ - OSSL_FUNC_keymgmt_import_fn *import; - OSSL_FUNC_keymgmt_import_types_fn *import_types; -# if OPENSSL_VERSION_NUMBER >= 0x30200000 - OSSL_FUNC_keymgmt_import_types_ex_fn *import_types_ex; -# endif - OSSL_FUNC_keymgmt_export_fn *export_fun; - OSSL_FUNC_keymgmt_export_types_fn *export_types; -# if OPENSSL_VERSION_NUMBER >= 0x30200000 - OSSL_FUNC_keymgmt_export_types_ex_fn *export_types_ex; -# endif - OSSL_FUNC_keymgmt_dup_fn *dup; -} UADK_RSA_KEYMGMT; - typedef struct { OSSL_LIB_CTX *libctx; RSA *rsa; @@ -1983,44 +1877,6 @@ free_pkey: return ret; }
-static EVP_SIGNATURE get_default_rsa_signature(void) -{ - static EVP_SIGNATURE s_signature; - static int initilazed; - - if (!initilazed) { - EVP_SIGNATURE *signature = - (EVP_SIGNATURE *)EVP_SIGNATURE_fetch(NULL, "RSA", "provider=default"); - if (signature) { - s_signature = *signature; - EVP_SIGNATURE_free((EVP_SIGNATURE *)signature); - initilazed = 1; - } else { - fprintf(stderr, "EVP_SIGNATURE_fetch from default provider failed"); - } - } - return s_signature; -} - -static EVP_ASYM_CIPHER get_default_asym_cipher(void) -{ - static EVP_ASYM_CIPHER s_asym_cipher; - static int initilazed; - - if (!initilazed) { - EVP_ASYM_CIPHER *asym_cipher = - (EVP_ASYM_CIPHER *)EVP_ASYM_CIPHER_fetch(NULL, "RSA", "provider=default"); - if (asym_cipher) { - s_asym_cipher = *asym_cipher; - EVP_ASYM_CIPHER_free((EVP_ASYM_CIPHER *)asym_cipher); - initilazed = 1; - } else { - fprintf(stderr, "EVP_ASYM_CIPHER_fetch from default provider failed"); - } - } - return s_asym_cipher; -} - static int uadk_rsa_asym_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[], int operation) { @@ -2080,26 +1936,26 @@ static int uadk_rsa_init(void *vprsactx, void *vrsa, return UADK_E_SUCCESS; }
-static int uadk_rsa_verify_recover_init(void *vprsactx, void *vrsa, - const OSSL_PARAM params[]) +static int uadk_signature_rsa_verify_recover_init(void *vprsactx, void *vrsa, + const OSSL_PARAM params[]) { return UADK_E_SUCCESS; }
-static int uadk_rsa_verify_recover(void *vprsactx, unsigned char *rout, - size_t *routlen, size_t routsize, - const unsigned char *sig, size_t siglen) +static int uadk_signature_rsa_verify_recover(void *vprsactx, unsigned char *rout, + size_t *routlen, size_t routsize, + const unsigned char *sig, size_t siglen) { return UADK_E_SUCCESS; }
-static int uadk_rsa_verify_init(void *vprsactx, void *vrsa, +static int uadk_signature_rsa_verify_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[]) { return uadk_rsa_init(vprsactx, vrsa, params, EVP_PKEY_OP_VERIFY); }
-static int uadk_rsa_verify(void *vprsactx, const unsigned char *sig, +static int uadk_signature_rsa_verify(void *vprsactx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen) { @@ -2134,13 +1990,13 @@ static int uadk_rsa_verify(void *vprsactx, const unsigned char *sig,
soft: fprintf(stderr, "switch to execute openssl software calculation.\n"); - if (!get_default_rsa_signature().verify) + if (!get_default_signature().verify) return UADK_E_FAIL;
- return get_default_rsa_signature().verify(vprsactx, sig, siglen, tbs, tbslen); + return get_default_signature().verify(vprsactx, sig, siglen, tbs, tbslen); }
-static int uadk_rsa_sign(void *vprsactx, unsigned char *sig, +static int uadk_signature_rsa_sign(void *vprsactx, unsigned char *sig, size_t *siglen, size_t sigsize, const unsigned char *tbs, size_t tbslen) { @@ -2180,18 +2036,18 @@ static int uadk_rsa_sign(void *vprsactx, unsigned char *sig, return UADK_E_SUCCESS; soft: fprintf(stderr, "switch to execute openssl software calculation.\n"); - if (!get_default_rsa_signature().sign) + if (!get_default_signature().sign) return UADK_E_FAIL;
- return get_default_rsa_signature().sign(vprsactx, sig, siglen, sigsize, tbs, tbslen); + return get_default_signature().sign(vprsactx, sig, siglen, sigsize, tbs, tbslen); }
-static int uadk_rsa_sign_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[]) +static int uadk_signature_rsa_sign_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[]) { return uadk_rsa_init(vprsactx, vrsa, params, EVP_PKEY_OP_SIGN); }
-static void *uadk_rsa_signature_newctx(void *provctx, const char *propq) +static void *uadk_signature_rsa_newctx(void *provctx, const char *propq) { PROV_RSA_SIG_CTX *priv = OPENSSL_zalloc(sizeof(PROV_RSA_SIG_CTX)); char *propq_copy = NULL; @@ -2216,7 +2072,7 @@ err: return NULL; }
-static void uadk_rsa_signature_freectx(void *vprsactx) +static void uadk_signature_rsa_freectx(void *vprsactx) { PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx;
@@ -2227,7 +2083,7 @@ static void uadk_rsa_signature_freectx(void *vprsactx) OPENSSL_clear_free(priv, sizeof(*priv)); }
-static void *uadk_rsa_asym_newctx(void *provctx) +static void *uadk_asym_cipher_rsa_newctx(void *provctx) { PROV_RSA_ASYM_CTX *priv = NULL;
@@ -2239,7 +2095,7 @@ static void *uadk_rsa_asym_newctx(void *provctx) return priv; }
-static void uadk_rsa_asym_freectx(void *vprsactx) +static void uadk_asym_cipher_rsa_freectx(void *vprsactx) { PROV_RSA_ASYM_CTX *priv = (PROV_RSA_ASYM_CTX *)vprsactx;
@@ -2249,7 +2105,7 @@ static void uadk_rsa_asym_freectx(void *vprsactx) OPENSSL_free(priv); }
-static int uadk_rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) +static int uadk_signature_rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) { PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx;
@@ -2281,8 +2137,8 @@ static const OSSL_PARAM settable_ctx_params_no_digest[] = { OSSL_PARAM_END };
-static const OSSL_PARAM *uadk_rsa_settable_ctx_params(void *vprsactx, - void *provctx) +static const OSSL_PARAM *uadk_signature_rsa_settable_ctx_params(void *vprsactx, + void *provctx) { PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx;
@@ -2292,16 +2148,16 @@ static const OSSL_PARAM *uadk_rsa_settable_ctx_params(void *vprsactx, return settable_ctx_params; }
-static int uadk_rsa_digest_sign_init(void *vprsactx, const char *mdname, - void *vrsa, const OSSL_PARAM params[]) +static int uadk_signature_rsa_digest_sign_init(void *vprsactx, const char *mdname, + void *vrsa, const OSSL_PARAM params[]) { - if (!get_default_rsa_signature().digest_sign_init) + if (!get_default_signature().digest_sign_init) return UADK_E_FAIL;
- return get_default_rsa_signature().digest_sign_init(vprsactx, mdname, vrsa, params); + return get_default_signature().digest_sign_init(vprsactx, mdname, vrsa, params); }
-static int uadk_rsa_digest_signverify_update(void *vprsactx, +static int uadk_signature_rsa_digest_sign_update(void *vprsactx, const unsigned char *data, size_t datalen) { @@ -2313,8 +2169,8 @@ static int uadk_rsa_digest_signverify_update(void *vprsactx, return EVP_DigestUpdate(priv->mdctx, data, datalen); }
-static int uadk_rsa_digest_sign_final(void *vprsactx, unsigned char *sig, - size_t *siglen, size_t sigsize) +static int uadk_signature_rsa_digest_sign_final(void *vprsactx, unsigned char *sig, + size_t *siglen, size_t sigsize) { PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx; unsigned char digest[EVP_MAX_MD_SIZE]; @@ -2339,20 +2195,29 @@ static int uadk_rsa_digest_sign_final(void *vprsactx, unsigned char *sig, return UADK_E_FAIL; }
- return uadk_rsa_sign(vprsactx, sig, siglen, sigsize, + return uadk_signature_rsa_sign(vprsactx, sig, siglen, sigsize, digest, (size_t)dlen); }
-static int uadk_rsa_digest_verify_init(void *vprsactx, const char *mdname, +static int uadk_signature_rsa_digest_verify_init(void *vprsactx, const char *mdname, void *vrsa, const OSSL_PARAM params[]) { - if (!get_default_rsa_signature().digest_verify_init) + if (!get_default_signature().digest_verify_init) return UADK_E_FAIL;
- return get_default_rsa_signature().digest_verify_init(vprsactx, mdname, vrsa, params); + return get_default_signature().digest_verify_init(vprsactx, mdname, vrsa, params); }
-static int uadk_rsa_digest_verify_final(void *vprsactx, const unsigned char *sig, +static int uadk_signature_rsa_digest_verify_update(void *vprsactx, const unsigned char *data, + size_t datalen) +{ + if (!get_default_signature().digest_verify_update) + return UADK_E_FAIL; + + return get_default_signature().digest_verify_update(vprsactx, data, datalen); +} + +static int uadk_signature_rsa_digest_verify_final(void *vprsactx, const unsigned char *sig, size_t siglen) { PROV_RSA_SIG_CTX *priv = (PROV_RSA_SIG_CTX *)vprsactx; @@ -2372,80 +2237,79 @@ static int uadk_rsa_digest_verify_final(void *vprsactx, const unsigned char *sig if (!EVP_DigestFinal_ex(priv->mdctx, digest, &dlen)) return UADK_E_FAIL;
- return uadk_rsa_verify(vprsactx, sig, siglen, - digest, (size_t)dlen); + return uadk_signature_rsa_verify(vprsactx, sig, siglen, digest, (size_t)dlen); }
-static void *uadk_rsa_dupctx(void *vprsactx) +static void *uadk_signature_rsa_dupctx(void *vprsactx) { - if (!get_default_rsa_signature().dupctx) + if (!get_default_signature().dupctx) return NULL;
- return get_default_rsa_signature().dupctx(vprsactx); + return get_default_signature().dupctx(vprsactx); }
-static int uadk_rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) +static int uadk_signature_rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) { - if (!get_default_rsa_signature().get_ctx_params) + if (!get_default_signature().get_ctx_params) return UADK_E_FAIL;
- return get_default_rsa_signature().get_ctx_params(vprsactx, params); + return get_default_signature().get_ctx_params(vprsactx, params); }
-static const OSSL_PARAM *uadk_rsa_gettable_ctx_md_params(void *vprsactx) +static const OSSL_PARAM *uadk_signature_rsa_gettable_ctx_md_params(void *vprsactx) { - if (!get_default_rsa_signature().gettable_ctx_md_params) + if (!get_default_signature().gettable_ctx_md_params) return NULL;
- return get_default_rsa_signature().gettable_ctx_md_params(vprsactx); + return get_default_signature().gettable_ctx_md_params(vprsactx); }
-static int uadk_rsa_set_ctx_md_params(void *vprsactx, const OSSL_PARAM params[]) +static int uadk_signature_rsa_set_ctx_md_params(void *vprsactx, const OSSL_PARAM params[]) { - if (!get_default_rsa_signature().set_ctx_md_params) + if (!get_default_signature().set_ctx_md_params) return UADK_E_FAIL;
- return get_default_rsa_signature().set_ctx_md_params(vprsactx, params); + return get_default_signature().set_ctx_md_params(vprsactx, params); }
-static const OSSL_PARAM *uadk_rsa_settable_ctx_md_params(void *vprsactx) +static const OSSL_PARAM *uadk_signature_rsa_settable_ctx_md_params(void *vprsactx) { - if (!get_default_rsa_signature().settable_ctx_md_params) + if (!get_default_signature().settable_ctx_md_params) return NULL;
- return get_default_rsa_signature().settable_ctx_md_params(vprsactx); + return get_default_signature().settable_ctx_md_params(vprsactx); }
-static const OSSL_PARAM *uadk_rsa_gettable_ctx_params(ossl_unused void *vprsactx, +static const OSSL_PARAM *uadk_signature_rsa_gettable_ctx_params(ossl_unused void *vprsactx, ossl_unused void *provctx) { - if (!get_default_rsa_signature().gettable_ctx_params) + if (!get_default_signature().gettable_ctx_params) return NULL;
- return get_default_rsa_signature().gettable_ctx_params(vprsactx, provctx); + return get_default_signature().gettable_ctx_params(vprsactx, provctx); }
-static int uadk_rsa_get_ctx_md_params(void *vprsactx, OSSL_PARAM *params) +static int uadk_signature_rsa_get_ctx_md_params(void *vprsactx, OSSL_PARAM *params) { - if (!get_default_rsa_signature().get_ctx_md_params) + if (!get_default_signature().get_ctx_md_params) return UADK_E_FAIL;
- return get_default_rsa_signature().get_ctx_md_params(vprsactx, params); + return get_default_signature().get_ctx_md_params(vprsactx, params); }
-static int uadk_rsa_asym_encrypt_init(void *vprsactx, void *vrsa, +static int uadk_asym_cipher_rsa_encrypt_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[]) { return uadk_rsa_asym_init(vprsactx, vrsa, params, EVP_PKEY_OP_ENCRYPT); }
-static int uadk_rsa_asym_decrypt_init(void *vprsactx, void *vrsa, +static int uadk_asym_cipher_rsa_decrypt_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[]) { return uadk_rsa_asym_init(vprsactx, vrsa, params, EVP_PKEY_OP_DECRYPT); }
-static int uadk_rsa_asym_encrypt(void *vprsactx, unsigned char *out, +static int uadk_asym_cipher_rsa_encrypt(void *vprsactx, unsigned char *out, size_t *outlen, size_t outsize, const unsigned char *in, size_t inlen) { @@ -2487,7 +2351,7 @@ soft: return get_default_asym_cipher().encrypt(vprsactx, out, outlen, outsize, in, inlen); }
-static int uadk_rsa_asym_decrypt(void *vprsactx, unsigned char *out, +static int uadk_asym_cipher_rsa_decrypt(void *vprsactx, unsigned char *out, size_t *outlen, size_t outsize, const unsigned char *in, size_t inlen) { @@ -2533,7 +2397,7 @@ soft: return get_default_asym_cipher().decrypt(vprsactx, out, outlen, outsize, in, inlen); }
-static int uadk_rsa_asym_get_ctx_params(void *vprsactx, OSSL_PARAM *params) +static int uadk_asym_cipher_rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) { if (!get_default_asym_cipher().get_ctx_params) return UADK_E_FAIL; @@ -2541,7 +2405,7 @@ static int uadk_rsa_asym_get_ctx_params(void *vprsactx, OSSL_PARAM *params) return get_default_asym_cipher().get_ctx_params(vprsactx, params); }
-static const OSSL_PARAM *uadk_rsa_asym_gettable_ctx_params(void *vprsactx, +static const OSSL_PARAM *uadk_asym_cipher_rsa_gettable_ctx_params(void *vprsactx, void *provctx) { if (!get_default_asym_cipher().gettable_ctx_params) @@ -2550,7 +2414,7 @@ static const OSSL_PARAM *uadk_rsa_asym_gettable_ctx_params(void *vprsactx, return get_default_asym_cipher().gettable_ctx_params(vprsactx, provctx); }
-static int uadk_rsa_asym_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) +static int uadk_asym_cipher_rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) { if (!get_default_asym_cipher().set_ctx_params) return UADK_E_FAIL; @@ -2558,7 +2422,7 @@ static int uadk_rsa_asym_set_ctx_params(void *vprsactx, const OSSL_PARAM params[ return get_default_asym_cipher().set_ctx_params(vprsactx, params); }
-static const OSSL_PARAM *uadk_rsa_asym_settable_ctx_params(void *vprsactx, +static const OSSL_PARAM *uadk_asym_cipher_rsa_settable_ctx_params(void *vprsactx, void *provctx) { if (!get_default_asym_cipher().settable_ctx_params) @@ -2567,27 +2431,7 @@ static const OSSL_PARAM *uadk_rsa_asym_settable_ctx_params(void *vprsactx, return get_default_asym_cipher().settable_ctx_params(vprsactx, provctx); }
-static UADK_RSA_KEYMGMT get_default_keymgmt(void) -{ - static UADK_RSA_KEYMGMT s_keymgmt; - static int initialized; - - if (!initialized) { - UADK_RSA_KEYMGMT *keymgmt = - (UADK_RSA_KEYMGMT *)EVP_KEYMGMT_fetch(NULL, "RSA", - "provider=default"); - if (keymgmt) { - s_keymgmt = *keymgmt; - EVP_KEYMGMT_free((EVP_KEYMGMT *)keymgmt); - initialized = 1; - } else { - fprintf(stderr, "EVP_KEYMGMT_fetch from default provider failed\n"); - } - } - return s_keymgmt; -} - -static void *uadk_keymgmt_rsa_newdata(void *provctx) +static void *uadk_keymgmt_rsa_new(void *provctx) { if (!get_default_keymgmt().new_fun) return NULL; @@ -2595,7 +2439,7 @@ static void *uadk_keymgmt_rsa_newdata(void *provctx) return get_default_keymgmt().new_fun(provctx); }
-static void uadk_keymgmt_rsa_freedata(void *keydata) +static void uadk_keymgmt_rsa_free(void *keydata) { if (!get_default_keymgmt().free) return; @@ -2644,6 +2488,16 @@ static int uadk_keymgmt_rsa_gen_set_params(void *genctx, const OSSL_PARAM params return get_default_keymgmt().gen_set_params(genctx, params); }
+static int uadk_keymgmt_rsa_gen_set_template(void *genctx, void *templates) +{ + if (!get_default_keymgmt().gen_set_template) { + fprintf(stderr, "failed to get keymgmt gen_set_template function\n"); + return UADK_P_FAIL; + } + + return get_default_keymgmt().gen_set_template(genctx, templates); +} + static const OSSL_PARAM *uadk_keymgmt_rsa_gen_settable_params(ossl_unused void *genctx, ossl_unused void *provctx) { @@ -2714,7 +2568,7 @@ static void *uadk_keymgmt_rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cba ret = uadk_prov_rsa_keygen(rsa, (int)gctx->nbits, gctx->pub_exp, gencb); if (ret == UADK_DO_SOFT || ret == UADK_E_FAIL) { BN_GENCB_free(gencb); - uadk_keymgmt_rsa_freedata(rsa); + uadk_keymgmt_rsa_free(rsa);
if (ret == UADK_DO_SOFT && SOFT_SWITCH) goto exe_soft; @@ -2767,6 +2621,26 @@ static const OSSL_PARAM *uadk_keymgmt_rsa_gettable_params(void *provctx) return get_default_keymgmt().gettable_params(provctx); }
+static int uadk_keymgmt_rsa_set_params(void *key, const OSSL_PARAM params[]) +{ + if (!get_default_keymgmt().set_params) { + fprintf(stderr, "failed to get keymgmt set_params function\n"); + return UADK_P_FAIL; + } + + return get_default_keymgmt().set_params(key, params); +} + +static const OSSL_PARAM *uadk_keymgmt_rsa_settable_params(ossl_unused void *provctx) +{ + if (!get_default_keymgmt().settable_params) { + fprintf(stderr, "failed to get keymgmt settable_params function\n"); + return NULL; + } + + return get_default_keymgmt().settable_params(provctx); +} + static int uadk_keymgmt_rsa_match(const void *keydata1, const void *keydata2, int selection) { if (!get_default_keymgmt().match) @@ -2808,105 +2682,12 @@ static void *uadk_keymgmt_rsa_dup(const void *keydata_from, int selection) return get_default_keymgmt().dup(keydata_from, selection); }
-const OSSL_DISPATCH uadk_rsa_keymgmt_functions[] = { - { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))uadk_keymgmt_rsa_newdata }, - { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))uadk_keymgmt_rsa_freedata }, - { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))uadk_keymgmt_rsa_has }, - { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))uadk_keymgmt_rsa_import }, - { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, - (void (*)(void))uadk_keymgmt_rsa_import_types }, - { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))uadk_keymgmt_rsa_gen_init }, - { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, - (void (*)(void))uadk_keymgmt_rsa_gen_set_params }, - { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, - (void (*)(void))uadk_keymgmt_rsa_gen_settable_params }, - { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))uadk_keymgmt_rsa_gen }, - { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))uadk_keymgmt_rsa_gen_cleanup }, - { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))uadk_keymgmt_rsa_load }, - { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))uadk_keymgmt_rsa_get_params }, - { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, - (void (*) (void))uadk_keymgmt_rsa_gettable_params }, - { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))uadk_keymgmt_rsa_match }, - { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))uadk_keymgmt_rsa_validate }, - { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))uadk_keymgmt_rsa_export }, - { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))uadk_keymgmt_rsa_export_types }, - { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))uadk_keymgmt_rsa_dup }, - {0, NULL} -}; - -const OSSL_DISPATCH uadk_rsa_signature_functions[] = { - {OSSL_FUNC_SIGNATURE_NEWCTX, - (void (*)(void))uadk_rsa_signature_newctx}, - {OSSL_FUNC_SIGNATURE_SIGN_INIT, - (void (*)(void))uadk_rsa_sign_init}, - {OSSL_FUNC_SIGNATURE_SIGN, - (void (*)(void))uadk_rsa_sign}, - {OSSL_FUNC_SIGNATURE_VERIFY_INIT, - (void (*)(void))uadk_rsa_verify_init }, - {OSSL_FUNC_SIGNATURE_VERIFY, - (void (*)(void))uadk_rsa_verify }, - {OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT, - (void (*)(void))uadk_rsa_verify_recover_init }, - {OSSL_FUNC_SIGNATURE_VERIFY_RECOVER, - (void (*)(void))uadk_rsa_verify_recover }, - {OSSL_FUNC_SIGNATURE_FREECTX, - (void (*)(void))uadk_rsa_signature_freectx}, - {OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, - (void (*)(void))uadk_rsa_set_ctx_params}, - {OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, - (void (*)(void))uadk_rsa_settable_ctx_params}, - {OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, - (void (*)(void))uadk_rsa_digest_sign_init }, - {OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, - (void (*)(void))uadk_rsa_digest_signverify_update }, - {OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, - (void (*)(void))uadk_rsa_digest_sign_final }, - {OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, - (void (*)(void))uadk_rsa_digest_verify_init }, - {OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, - (void (*)(void))uadk_rsa_digest_signverify_update }, - {OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, - (void (*)(void))uadk_rsa_digest_verify_final }, - {OSSL_FUNC_SIGNATURE_DUPCTX, - (void (*)(void))uadk_rsa_dupctx }, - {OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, - (void (*)(void))uadk_rsa_get_ctx_params }, - {OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, - (void (*)(void))uadk_rsa_gettable_ctx_params }, - {OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS, - (void (*)(void))uadk_rsa_get_ctx_md_params }, - {OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS, - (void (*)(void))uadk_rsa_gettable_ctx_md_params }, - {OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS, - (void (*)(void))uadk_rsa_set_ctx_md_params }, - {OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, - (void (*)(void))uadk_rsa_settable_ctx_md_params }, - {0, NULL} -}; - -const OSSL_DISPATCH uadk_rsa_asym_cipher_functions[] = { - { OSSL_FUNC_ASYM_CIPHER_NEWCTX, - (void (*)(void))uadk_rsa_asym_newctx }, - { OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT, - (void (*)(void))uadk_rsa_asym_encrypt_init }, - { OSSL_FUNC_ASYM_CIPHER_ENCRYPT, - (void (*)(void))uadk_rsa_asym_encrypt }, - { OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT, - (void (*)(void))uadk_rsa_asym_decrypt_init }, - { OSSL_FUNC_ASYM_CIPHER_DECRYPT, - (void (*)(void))uadk_rsa_asym_decrypt }, - { OSSL_FUNC_ASYM_CIPHER_FREECTX, - (void (*)(void))uadk_rsa_asym_freectx }, - { OSSL_FUNC_ASYM_CIPHER_GET_CTX_PARAMS, - (void (*)(void))uadk_rsa_asym_get_ctx_params }, - { OSSL_FUNC_ASYM_CIPHER_GETTABLE_CTX_PARAMS, - (void (*)(void))uadk_rsa_asym_gettable_ctx_params }, - { OSSL_FUNC_ASYM_CIPHER_SET_CTX_PARAMS, - (void (*)(void))uadk_rsa_asym_set_ctx_params }, - { OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS, - (void (*)(void))uadk_rsa_asym_settable_ctx_params }, - { 0, NULL } -}; +static void *uadk_asym_cipher_rsa_dupctx(void *vprsactx) +{ + if (!get_default_asym_cipher().dupctx) + return UADK_E_FAIL; + return get_default_asym_cipher().dupctx(vprsactx); +}
void uadk_prov_destroy_rsa(void) { diff --git a/src/uadk_prov_sm2.c b/src/uadk_prov_sm2.c index 19d983a..9f9be6f 100644 --- a/src/uadk_prov_sm2.c +++ b/src/uadk_prov_sm2.c @@ -2273,6 +2273,19 @@ static const OSSL_PARAM *uadk_signature_sm2_gettable_ctx_md_params(void *vpsm2ct return EVP_MD_gettable_ctx_params(smctx->sm2_md->md); }
+static int uadk_signature_sm2_verify_recover_init(void *vpsm2ctx, void *vsm2, + const OSSL_PARAM params[]) +{ + return UADK_P_SUCCESS; +} + +static int uadk_signature_sm2_verify_recover(void *vpsm2ctx, unsigned char *rout, + size_t *routlen, size_t routsize, + const unsigned char *sig, size_t siglen) +{ + return UADK_P_SUCCESS; +} + static void *uadk_asym_cipher_sm2_newctx(void *provctx) { PROV_SM2_ASYM_CTX *psm2ctx = OPENSSL_zalloc(sizeof(PROV_SM2_ASYM_CTX));
Rename get_default_xxx() function with algorithm specific name, avoid functions with the same name but different implementations.
Signed-off-by: Zhiqi Song songzhiqi1@huawei.com Signed-off-by: Qi Tao taoqi10@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_prov.h | 11 ++- src/uadk_prov_dh.c | 80 ++++++++++----------- src/uadk_prov_pkey.h | 8 +-- src/uadk_prov_rsa.c | 163 +++++++++++++++++++++---------------------- src/uadk_prov_sm2.c | 81 +++++++++++---------- 5 files changed, 174 insertions(+), 169 deletions(-)
diff --git a/src/uadk_prov.h b/src/uadk_prov.h index fa649ed..c66cdc7 100644 --- a/src/uadk_prov.h +++ b/src/uadk_prov.h @@ -17,8 +17,15 @@ */ #ifndef UADK_PROV_H #define UADK_PROV_H - -#define FUNC_MAX_NUM 32 +#include <openssl/core_dispatch.h> + +#define FUNC_MAX_NUM 32 +#define CTX_ASYNC 1 +#define CTX_SYNC 0 +#define UADK_UNINIT 0 +#define UADK_INIT_SUCCESS 1 +#define UADK_INIT_FAIL 2 +#define UADK_DEVICE_ERROR 3
/* Copy openssl/providers/implementations/include/prov/names.h */ #define PROV_NAMES_SHA2_224 "SHA2-224:SHA-224:SHA224:2.16.840.1.101.3.4.2.4" diff --git a/src/uadk_prov_dh.c b/src/uadk_prov_dh.c index b7184c0..c05df15 100644 --- a/src/uadk_prov_dh.c +++ b/src/uadk_prov_dh.c @@ -192,165 +192,165 @@ typedef struct {
static void *uadk_keymgmt_dh_new(void *provctx) { - if (get_default_keymgmt().new_fun == NULL) + if (get_default_dh_keymgmt().new_fun == NULL) return NULL;
- return get_default_keymgmt().new_fun(provctx); + return get_default_dh_keymgmt().new_fun(provctx); }
static void uadk_keymgmt_dh_free(void *keydata) { - if (get_default_keymgmt().free == NULL) + if (get_default_dh_keymgmt().free == NULL) return;
- get_default_keymgmt().free(keydata); + get_default_dh_keymgmt().free(keydata); }
static int uadk_keymgmt_dh_has(const void *keydata, int selection) { - if (get_default_keymgmt().has == NULL) + if (get_default_dh_keymgmt().has == NULL) return UADK_P_FAIL;
- return get_default_keymgmt().has(keydata, selection); + return get_default_dh_keymgmt().has(keydata, selection); }
static int uadk_keymgmt_dh_match(const void *keydata1, const void *keydata2, int selection) { - if (get_default_keymgmt().match == NULL) + if (get_default_dh_keymgmt().match == NULL) return UADK_P_FAIL;
- return get_default_keymgmt().match(keydata1, keydata2, selection); + return get_default_dh_keymgmt().match(keydata1, keydata2, selection); }
static int uadk_keymgmt_dh_import(void *keydata, int selection, const OSSL_PARAM params[]) { - if (get_default_keymgmt().import == NULL) + if (get_default_dh_keymgmt().import == NULL) return UADK_P_FAIL;
- return get_default_keymgmt().import(keydata, selection, params); + return get_default_dh_keymgmt().import(keydata, selection, params); }
static int uadk_keymgmt_dh_export(void *keydata, int selection, OSSL_CALLBACK *cb, void *cb_params) { - if (get_default_keymgmt().export_fun == NULL) + if (get_default_dh_keymgmt().export_fun == NULL) return UADK_P_FAIL;
- return get_default_keymgmt().export_fun(keydata, selection, cb, cb_params); + return get_default_dh_keymgmt().export_fun(keydata, selection, cb, cb_params); }
static const OSSL_PARAM *uadk_keymgmt_dh_import_types(int selection) { - if (get_default_keymgmt().import_types == NULL) + if (get_default_dh_keymgmt().import_types == NULL) return NULL;
- return get_default_keymgmt().import_types(selection); + return get_default_dh_keymgmt().import_types(selection); }
static const OSSL_PARAM *uadk_keymgmt_dh_export_types(int selection) { - if (get_default_keymgmt().export_types == NULL) + if (get_default_dh_keymgmt().export_types == NULL) return NULL;
- return get_default_keymgmt().export_types(selection); + return get_default_dh_keymgmt().export_types(selection); }
static ossl_inline int uadk_keymgmt_dh_get_params(void *key, OSSL_PARAM params[]) { - if (get_default_keymgmt().get_params == NULL) + if (get_default_dh_keymgmt().get_params == NULL) return UADK_P_FAIL;
- return get_default_keymgmt().get_params(key, params); + return get_default_dh_keymgmt().get_params(key, params); }
static const OSSL_PARAM *uadk_keymgmt_dh_gettable_params(void *provctx) { - if (get_default_keymgmt().gettable_params == NULL) + if (get_default_dh_keymgmt().gettable_params == NULL) return NULL;
- return get_default_keymgmt().gettable_params(provctx); + return get_default_dh_keymgmt().gettable_params(provctx); }
static const OSSL_PARAM *uadk_keymgmt_dh_settable_params(void *provctx) { - if (get_default_keymgmt().settable_params == NULL) + if (get_default_dh_keymgmt().settable_params == NULL) return NULL;
- return get_default_keymgmt().settable_params(provctx); + return get_default_dh_keymgmt().settable_params(provctx); }
static int uadk_keymgmt_dh_set_params(void *key, const OSSL_PARAM params[]) { - if (get_default_keymgmt().set_params == NULL) + if (get_default_dh_keymgmt().set_params == NULL) return UADK_P_FAIL;
- return get_default_keymgmt().set_params(key, params); + return get_default_dh_keymgmt().set_params(key, params); }
static int uadk_keymgmt_dh_validate(const void *keydata, int selection, int checktype) { - if (get_default_keymgmt().validate == NULL) + if (get_default_dh_keymgmt().validate == NULL) return UADK_P_FAIL;
- return get_default_keymgmt().validate(keydata, selection, checktype); + return get_default_dh_keymgmt().validate(keydata, selection, checktype); }
static void *uadk_keymgmt_dh_gen_init(void *provctx, int selection, const OSSL_PARAM params[]) { - if (get_default_keymgmt().gen_init == NULL) + if (get_default_dh_keymgmt().gen_init == NULL) return NULL;
- return get_default_keymgmt().gen_init(provctx, selection, params); + return get_default_dh_keymgmt().gen_init(provctx, selection, params); }
static int uadk_keymgmt_dh_gen_set_template(void *genctx, void *templ) { - if (get_default_keymgmt().gen_set_template == NULL) + if (get_default_dh_keymgmt().gen_set_template == NULL) return UADK_P_FAIL;
- return get_default_keymgmt().gen_set_template(genctx, templ); + return get_default_dh_keymgmt().gen_set_template(genctx, templ); }
static const OSSL_PARAM *uadk_keymgmt_dh_gen_settable_params(ossl_unused void *genctx, ossl_unused void *provctx) { - if (get_default_keymgmt().gen_settable_params == NULL) + if (get_default_dh_keymgmt().gen_settable_params == NULL) return NULL;
- return get_default_keymgmt().gen_settable_params(genctx, provctx); + return get_default_dh_keymgmt().gen_settable_params(genctx, provctx); }
static int uadk_keymgmt_dh_gen_set_params(void *genctx, const OSSL_PARAM params[]) { - if (get_default_keymgmt().gen_set_params == NULL) + if (get_default_dh_keymgmt().gen_set_params == NULL) return UADK_P_FAIL;
- return get_default_keymgmt().gen_set_params(genctx, params); + return get_default_dh_keymgmt().gen_set_params(genctx, params); }
static void uadk_keymgmt_dh_gen_cleanup(void *genctx) { - if (get_default_keymgmt().gen_cleanup == NULL) + if (get_default_dh_keymgmt().gen_cleanup == NULL) return;
- get_default_keymgmt().gen_cleanup(genctx); + get_default_dh_keymgmt().gen_cleanup(genctx); }
static void *uadk_keymgmt_dh_load(const void *reference, size_t reference_sz) { - if (get_default_keymgmt().load == NULL) + if (get_default_dh_keymgmt().load == NULL) return NULL;
- return get_default_keymgmt().load(reference, reference_sz); + return get_default_dh_keymgmt().load(reference, reference_sz); }
static void *uadk_keymgmt_dh_dup(const void *keydata_from, int selection) { - if (get_default_keymgmt().dup == NULL) + if (get_default_dh_keymgmt().dup == NULL) return NULL;
- return get_default_keymgmt().dup(keydata_from, selection); + return get_default_dh_keymgmt().dup(keydata_from, selection); }
static int uadk_DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) diff --git a/src/uadk_prov_pkey.h b/src/uadk_prov_pkey.h index a1805e6..d61e966 100644 --- a/src/uadk_prov_pkey.h +++ b/src/uadk_prov_pkey.h @@ -168,7 +168,7 @@ static OSSL_FUNC_keymgmt_import_types_fn uadk_keymgmt_##nm##_import_types; \ static OSSL_FUNC_keymgmt_export_fn uadk_keymgmt_##nm##_export; \ static OSSL_FUNC_keymgmt_export_types_fn uadk_keymgmt_##nm##_export_types; \ static OSSL_FUNC_keymgmt_dup_fn uadk_keymgmt_##nm##_dup; \ -static UADK_PKEY_KEYMGMT get_default_keymgmt(void) \ +static UADK_PKEY_KEYMGMT get_default_##nm##_keymgmt(void) \ { \ static UADK_PKEY_KEYMGMT s_keymgmt; \ static int initilazed; \ @@ -277,7 +277,7 @@ static OSSL_FUNC_signature_get_ctx_md_params_fn uadk_signature_##nm##_get_ctx_md static OSSL_FUNC_signature_gettable_ctx_md_params_fn uadk_signature_##nm##_gettable_ctx_md_params; \ static OSSL_FUNC_signature_set_ctx_md_params_fn uadk_signature_##nm##_set_ctx_md_params; \ static OSSL_FUNC_signature_settable_ctx_md_params_fn uadk_signature_##nm##_settable_ctx_md_params; \ -static UADK_PKEY_SIGNATURE get_default_signature(void) \ +static UADK_PKEY_SIGNATURE get_default_##nm##_signature(void) \ { \ static UADK_PKEY_SIGNATURE s_signature; \ static int initilazed; \ @@ -373,7 +373,7 @@ static OSSL_FUNC_asym_cipher_get_ctx_params_fn uadk_asym_cipher_##nm##_get_ctx_p static OSSL_FUNC_asym_cipher_gettable_ctx_params_fn uadk_asym_cipher_##nm##_gettable_ctx_params; \ static OSSL_FUNC_asym_cipher_set_ctx_params_fn uadk_asym_cipher_##nm##_set_ctx_params; \ static OSSL_FUNC_asym_cipher_settable_ctx_params_fn uadk_asym_cipher_##nm##_settable_ctx_params; \ -static UADK_PKEY_ASYM_CIPHER get_default_asym_cipher(void) \ +static UADK_PKEY_ASYM_CIPHER get_default_##nm##_asym_cipher(void) \ { \ static UADK_PKEY_ASYM_CIPHER s_asym_cipher; \ static int initilazed; \ @@ -444,7 +444,7 @@ typedef struct { static OSSL_FUNC_keyexch_settable_ctx_params_fn uadk_keyexch_##nm##_settable_ctx_params; \ static OSSL_FUNC_keyexch_get_ctx_params_fn uadk_keyexch_##nm##_get_ctx_params; \ static OSSL_FUNC_keyexch_gettable_ctx_params_fn uadk_keyexch_##nm##_gettable_ctx_params; \ -static UADK_PKEY_KEYEXCH get_default_keyexch(void) \ +static UADK_PKEY_KEYEXCH get_default_##nm##_keyexch(void) \ { \ UADK_PKEY_KEYEXCH s_keyexch; \ static int initilazed; \ diff --git a/src/uadk_prov_rsa.c b/src/uadk_prov_rsa.c index 15f72eb..e34562b 100644 --- a/src/uadk_prov_rsa.c +++ b/src/uadk_prov_rsa.c @@ -27,7 +27,6 @@ #include <uadk/wd_rsa.h> #include <uadk/wd_sched.h> #include "uadk_async.h" -#include "uadk.h" #include "uadk_prov.h" #include "uadk_prov_pkey.h"
@@ -969,7 +968,7 @@ static int uadk_rsa_env_poll(void *ctx) if (ret < 0 || recv == expt) return ret; rx_cnt++; - } while (rx_cnt < ENGINE_RECV_MAX_CNT); + } while (rx_cnt < PROV_RECV_MAX_CNT);
fprintf(stderr, "failed to poll msg: timeout!\n");
@@ -1990,10 +1989,10 @@ static int uadk_signature_rsa_verify(void *vprsactx, const unsigned char *sig,
soft: fprintf(stderr, "switch to execute openssl software calculation.\n"); - if (!get_default_signature().verify) + if (!get_default_rsa_signature().verify) return UADK_E_FAIL;
- return get_default_signature().verify(vprsactx, sig, siglen, tbs, tbslen); + return get_default_rsa_signature().verify(vprsactx, sig, siglen, tbs, tbslen); }
static int uadk_signature_rsa_sign(void *vprsactx, unsigned char *sig, @@ -2036,10 +2035,10 @@ static int uadk_signature_rsa_sign(void *vprsactx, unsigned char *sig, return UADK_E_SUCCESS; soft: fprintf(stderr, "switch to execute openssl software calculation.\n"); - if (!get_default_signature().sign) + if (!get_default_rsa_signature().sign) return UADK_E_FAIL;
- return get_default_signature().sign(vprsactx, sig, siglen, sigsize, tbs, tbslen); + return get_default_rsa_signature().sign(vprsactx, sig, siglen, sigsize, tbs, tbslen); }
static int uadk_signature_rsa_sign_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[]) @@ -2151,10 +2150,10 @@ static const OSSL_PARAM *uadk_signature_rsa_settable_ctx_params(void *vprsactx, static int uadk_signature_rsa_digest_sign_init(void *vprsactx, const char *mdname, void *vrsa, const OSSL_PARAM params[]) { - if (!get_default_signature().digest_sign_init) + if (!get_default_rsa_signature().digest_sign_init) return UADK_E_FAIL;
- return get_default_signature().digest_sign_init(vprsactx, mdname, vrsa, params); + return get_default_rsa_signature().digest_sign_init(vprsactx, mdname, vrsa, params); }
static int uadk_signature_rsa_digest_sign_update(void *vprsactx, @@ -2202,19 +2201,19 @@ static int uadk_signature_rsa_digest_sign_final(void *vprsactx, unsigned char *s static int uadk_signature_rsa_digest_verify_init(void *vprsactx, const char *mdname, void *vrsa, const OSSL_PARAM params[]) { - if (!get_default_signature().digest_verify_init) + if (!get_default_rsa_signature().digest_verify_init) return UADK_E_FAIL;
- return get_default_signature().digest_verify_init(vprsactx, mdname, vrsa, params); + return get_default_rsa_signature().digest_verify_init(vprsactx, mdname, vrsa, params); }
static int uadk_signature_rsa_digest_verify_update(void *vprsactx, const unsigned char *data, size_t datalen) { - if (!get_default_signature().digest_verify_update) + if (!get_default_rsa_signature().digest_verify_update) return UADK_E_FAIL;
- return get_default_signature().digest_verify_update(vprsactx, data, datalen); + return get_default_rsa_signature().digest_verify_update(vprsactx, data, datalen); }
static int uadk_signature_rsa_digest_verify_final(void *vprsactx, const unsigned char *sig, @@ -2242,59 +2241,59 @@ static int uadk_signature_rsa_digest_verify_final(void *vprsactx, const unsigned
static void *uadk_signature_rsa_dupctx(void *vprsactx) { - if (!get_default_signature().dupctx) + if (!get_default_rsa_signature().dupctx) return NULL;
- return get_default_signature().dupctx(vprsactx); + return get_default_rsa_signature().dupctx(vprsactx); }
static int uadk_signature_rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) { - if (!get_default_signature().get_ctx_params) + if (!get_default_rsa_signature().get_ctx_params) return UADK_E_FAIL;
- return get_default_signature().get_ctx_params(vprsactx, params); + return get_default_rsa_signature().get_ctx_params(vprsactx, params); }
static const OSSL_PARAM *uadk_signature_rsa_gettable_ctx_md_params(void *vprsactx) { - if (!get_default_signature().gettable_ctx_md_params) + if (!get_default_rsa_signature().gettable_ctx_md_params) return NULL;
- return get_default_signature().gettable_ctx_md_params(vprsactx); + return get_default_rsa_signature().gettable_ctx_md_params(vprsactx); }
static int uadk_signature_rsa_set_ctx_md_params(void *vprsactx, const OSSL_PARAM params[]) { - if (!get_default_signature().set_ctx_md_params) + if (!get_default_rsa_signature().set_ctx_md_params) return UADK_E_FAIL;
- return get_default_signature().set_ctx_md_params(vprsactx, params); + return get_default_rsa_signature().set_ctx_md_params(vprsactx, params); }
static const OSSL_PARAM *uadk_signature_rsa_settable_ctx_md_params(void *vprsactx) { - if (!get_default_signature().settable_ctx_md_params) + if (!get_default_rsa_signature().settable_ctx_md_params) return NULL;
- return get_default_signature().settable_ctx_md_params(vprsactx); + return get_default_rsa_signature().settable_ctx_md_params(vprsactx); }
static const OSSL_PARAM *uadk_signature_rsa_gettable_ctx_params(ossl_unused void *vprsactx, ossl_unused void *provctx) { - if (!get_default_signature().gettable_ctx_params) + if (!get_default_rsa_signature().gettable_ctx_params) return NULL;
- return get_default_signature().gettable_ctx_params(vprsactx, provctx); + return get_default_rsa_signature().gettable_ctx_params(vprsactx, provctx); }
static int uadk_signature_rsa_get_ctx_md_params(void *vprsactx, OSSL_PARAM *params) { - if (!get_default_signature().get_ctx_md_params) + if (!get_default_rsa_signature().get_ctx_md_params) return UADK_E_FAIL;
- return get_default_signature().get_ctx_md_params(vprsactx, params); + return get_default_rsa_signature().get_ctx_md_params(vprsactx, params); }
static int uadk_asym_cipher_rsa_encrypt_init(void *vprsactx, void *vrsa, @@ -2345,10 +2344,10 @@ static int uadk_asym_cipher_rsa_encrypt(void *vprsactx, unsigned char *out, return UADK_E_SUCCESS; soft: fprintf(stderr, "switch to execute openssl software calculation.\n"); - if (!get_default_asym_cipher().encrypt) + if (!get_default_rsa_asym_cipher().encrypt) return UADK_E_FAIL;
- return get_default_asym_cipher().encrypt(vprsactx, out, outlen, outsize, in, inlen); + return get_default_rsa_asym_cipher().encrypt(vprsactx, out, outlen, outsize, in, inlen); }
static int uadk_asym_cipher_rsa_decrypt(void *vprsactx, unsigned char *out, @@ -2391,120 +2390,120 @@ static int uadk_asym_cipher_rsa_decrypt(void *vprsactx, unsigned char *out, return UADK_E_SUCCESS; soft: fprintf(stderr, "switch to execute openssl software calculation.\n"); - if (!get_default_asym_cipher().decrypt) + if (!get_default_rsa_asym_cipher().decrypt) return UADK_E_FAIL;
- return get_default_asym_cipher().decrypt(vprsactx, out, outlen, outsize, in, inlen); + return get_default_rsa_asym_cipher().decrypt(vprsactx, out, outlen, outsize, in, inlen); }
static int uadk_asym_cipher_rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) { - if (!get_default_asym_cipher().get_ctx_params) + if (!get_default_rsa_asym_cipher().get_ctx_params) return UADK_E_FAIL;
- return get_default_asym_cipher().get_ctx_params(vprsactx, params); + return get_default_rsa_asym_cipher().get_ctx_params(vprsactx, params); }
static const OSSL_PARAM *uadk_asym_cipher_rsa_gettable_ctx_params(void *vprsactx, void *provctx) { - if (!get_default_asym_cipher().gettable_ctx_params) + if (!get_default_rsa_asym_cipher().gettable_ctx_params) return UADK_E_FAIL;
- return get_default_asym_cipher().gettable_ctx_params(vprsactx, provctx); + return get_default_rsa_asym_cipher().gettable_ctx_params(vprsactx, provctx); }
static int uadk_asym_cipher_rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) { - if (!get_default_asym_cipher().set_ctx_params) + if (!get_default_rsa_asym_cipher().set_ctx_params) return UADK_E_FAIL;
- return get_default_asym_cipher().set_ctx_params(vprsactx, params); + return get_default_rsa_asym_cipher().set_ctx_params(vprsactx, params); }
static const OSSL_PARAM *uadk_asym_cipher_rsa_settable_ctx_params(void *vprsactx, void *provctx) { - if (!get_default_asym_cipher().settable_ctx_params) + if (!get_default_rsa_asym_cipher().settable_ctx_params) return UADK_E_FAIL;
- return get_default_asym_cipher().settable_ctx_params(vprsactx, provctx); + return get_default_rsa_asym_cipher().settable_ctx_params(vprsactx, provctx); }
static void *uadk_keymgmt_rsa_new(void *provctx) { - if (!get_default_keymgmt().new_fun) + if (!get_default_rsa_keymgmt().new_fun) return NULL;
- return get_default_keymgmt().new_fun(provctx); + return get_default_rsa_keymgmt().new_fun(provctx); }
static void uadk_keymgmt_rsa_free(void *keydata) { - if (!get_default_keymgmt().free) + if (!get_default_rsa_keymgmt().free) return;
- get_default_keymgmt().free(keydata); + get_default_rsa_keymgmt().free(keydata); }
static int uadk_keymgmt_rsa_has(const void *keydata, int selection) { - if (!get_default_keymgmt().has) + if (!get_default_rsa_keymgmt().has) return UADK_E_FAIL;
- return get_default_keymgmt().has(keydata, selection); + return get_default_rsa_keymgmt().has(keydata, selection); }
static int uadk_keymgmt_rsa_import(void *keydata, int selection, const OSSL_PARAM params[]) { - if (!get_default_keymgmt().import) + if (!get_default_rsa_keymgmt().import) return UADK_E_FAIL;
- return get_default_keymgmt().import(keydata, selection, params); + return get_default_rsa_keymgmt().import(keydata, selection, params); }
static const OSSL_PARAM *uadk_keymgmt_rsa_import_types(int selection) { - if (!get_default_keymgmt().import_types) + if (!get_default_rsa_keymgmt().import_types) return NULL;
- return get_default_keymgmt().import_types(selection); + return get_default_rsa_keymgmt().import_types(selection); }
static void *uadk_keymgmt_rsa_gen_init(void *provctx, int selection, const OSSL_PARAM params[]) { - if (!get_default_keymgmt().gen_init) + if (!get_default_rsa_keymgmt().gen_init) return NULL;
- return get_default_keymgmt().gen_init(provctx, selection, params); + return get_default_rsa_keymgmt().gen_init(provctx, selection, params); }
static int uadk_keymgmt_rsa_gen_set_params(void *genctx, const OSSL_PARAM params[]) { - if (!get_default_keymgmt().gen_set_params) + if (!get_default_rsa_keymgmt().gen_set_params) return UADK_E_FAIL;
- return get_default_keymgmt().gen_set_params(genctx, params); + return get_default_rsa_keymgmt().gen_set_params(genctx, params); }
static int uadk_keymgmt_rsa_gen_set_template(void *genctx, void *templates) { - if (!get_default_keymgmt().gen_set_template) { + if (!get_default_rsa_keymgmt().gen_set_template) { fprintf(stderr, "failed to get keymgmt gen_set_template function\n"); return UADK_P_FAIL; }
- return get_default_keymgmt().gen_set_template(genctx, templates); + return get_default_rsa_keymgmt().gen_set_template(genctx, templates); }
static const OSSL_PARAM *uadk_keymgmt_rsa_gen_settable_params(ossl_unused void *genctx, ossl_unused void *provctx) { - if (!get_default_keymgmt().gen_settable_params) + if (!get_default_rsa_keymgmt().gen_settable_params) return NULL;
- return get_default_keymgmt().gen_settable_params(genctx, provctx); + return get_default_rsa_keymgmt().gen_settable_params(genctx, provctx); }
static int rsa_gencb(int p, int n, BN_GENCB *cb) @@ -2584,109 +2583,109 @@ static void *uadk_keymgmt_rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cba
exe_soft: fprintf(stderr, "switch to execute openssl software calculation.\n"); - if (!get_default_keymgmt().gen) + if (!get_default_rsa_keymgmt().gen) return NULL; - return get_default_keymgmt().gen(genctx, osslcb, cbarg); + return get_default_rsa_keymgmt().gen(genctx, osslcb, cbarg); }
static void uadk_keymgmt_rsa_gen_cleanup(void *genctx) { - if (!get_default_keymgmt().gen_cleanup) + if (!get_default_rsa_keymgmt().gen_cleanup) return;
- get_default_keymgmt().gen_cleanup(genctx); + get_default_rsa_keymgmt().gen_cleanup(genctx); }
static void *uadk_keymgmt_rsa_load(const void *reference, size_t reference_sz) { - if (!get_default_keymgmt().load) + if (!get_default_rsa_keymgmt().load) return NULL;
- return get_default_keymgmt().load(reference, reference_sz); + return get_default_rsa_keymgmt().load(reference, reference_sz); }
static int uadk_keymgmt_rsa_get_params(void *key, OSSL_PARAM params[]) { - if (!get_default_keymgmt().get_params) + if (!get_default_rsa_keymgmt().get_params) return UADK_E_FAIL;
- return get_default_keymgmt().get_params(key, params); + return get_default_rsa_keymgmt().get_params(key, params); }
static const OSSL_PARAM *uadk_keymgmt_rsa_gettable_params(void *provctx) { - if (!get_default_keymgmt().gettable_params) + if (!get_default_rsa_keymgmt().gettable_params) return NULL;
- return get_default_keymgmt().gettable_params(provctx); + return get_default_rsa_keymgmt().gettable_params(provctx); }
static int uadk_keymgmt_rsa_set_params(void *key, const OSSL_PARAM params[]) { - if (!get_default_keymgmt().set_params) { + if (!get_default_rsa_keymgmt().set_params) { fprintf(stderr, "failed to get keymgmt set_params function\n"); return UADK_P_FAIL; }
- return get_default_keymgmt().set_params(key, params); + return get_default_rsa_keymgmt().set_params(key, params); }
static const OSSL_PARAM *uadk_keymgmt_rsa_settable_params(ossl_unused void *provctx) { - if (!get_default_keymgmt().settable_params) { + if (!get_default_rsa_keymgmt().settable_params) { fprintf(stderr, "failed to get keymgmt settable_params function\n"); return NULL; }
- return get_default_keymgmt().settable_params(provctx); + return get_default_rsa_keymgmt().settable_params(provctx); }
static int uadk_keymgmt_rsa_match(const void *keydata1, const void *keydata2, int selection) { - if (!get_default_keymgmt().match) + if (!get_default_rsa_keymgmt().match) return UADK_E_FAIL;
- return get_default_keymgmt().match(keydata1, keydata2, selection); + return get_default_rsa_keymgmt().match(keydata1, keydata2, selection); }
static int uadk_keymgmt_rsa_validate(const void *keydata, int selection, int checktype) { - if (!get_default_keymgmt().validate) + if (!get_default_rsa_keymgmt().validate) return UADK_E_FAIL;
- return get_default_keymgmt().validate(keydata, selection, checktype); + return get_default_rsa_keymgmt().validate(keydata, selection, checktype); }
static int uadk_keymgmt_rsa_export(void *keydata, int selection, OSSL_CALLBACK *param_callback, void *cbarg) { - if (!get_default_keymgmt().export_fun) + if (!get_default_rsa_keymgmt().export_fun) return UADK_E_FAIL;
- return get_default_keymgmt().export_fun(keydata, selection, param_callback, cbarg); + return get_default_rsa_keymgmt().export_fun(keydata, selection, param_callback, cbarg); }
static const OSSL_PARAM *uadk_keymgmt_rsa_export_types(int selection) { - if (!get_default_keymgmt().export_types) + if (!get_default_rsa_keymgmt().export_types) return NULL;
- return get_default_keymgmt().export_types(selection); + return get_default_rsa_keymgmt().export_types(selection); }
static void *uadk_keymgmt_rsa_dup(const void *keydata_from, int selection) { - if (!get_default_keymgmt().dup) + if (!get_default_rsa_keymgmt().dup) return NULL;
- return get_default_keymgmt().dup(keydata_from, selection); + return get_default_rsa_keymgmt().dup(keydata_from, selection); }
static void *uadk_asym_cipher_rsa_dupctx(void *vprsactx) { - if (!get_default_asym_cipher().dupctx) + if (!get_default_rsa_asym_cipher().dupctx) return UADK_E_FAIL; - return get_default_asym_cipher().dupctx(vprsactx); + return get_default_rsa_asym_cipher().dupctx(vprsactx); }
void uadk_prov_destroy_rsa(void) diff --git a/src/uadk_prov_sm2.c b/src/uadk_prov_sm2.c index 9f9be6f..1e0bd5a 100644 --- a/src/uadk_prov_sm2.c +++ b/src/uadk_prov_sm2.c @@ -22,7 +22,6 @@ #include <openssl/bn.h> #include <uadk/wd_ecc.h> #include <uadk/wd_sched.h> -#include "uadk.h" #include "uadk_async.h" #include "uadk_prov.h" #include "uadk_prov_der_writer.h" @@ -208,12 +207,12 @@ IMPLEMENT_ASN1_FUNCTIONS(SM2_Ciphertext) */ static void *uadk_keymgmt_sm2_new(void *provctx) { - if (!get_default_keymgmt().new_fun) { + if (!get_default_sm2_keymgmt().new_fun) { fprintf(stderr, "failed to get keymgmt new function\n"); return NULL; }
- return get_default_keymgmt().new_fun(provctx); + return get_default_sm2_keymgmt().new_fun(provctx); }
/** @@ -223,92 +222,92 @@ static void *uadk_keymgmt_sm2_new(void *provctx) */ static void uadk_keymgmt_sm2_free(void *keydata) { - if (!get_default_keymgmt().free) { + if (!get_default_sm2_keymgmt().free) { fprintf(stderr, "failed to get keymgmt free function\n"); return; }
- get_default_keymgmt().free(keydata); + get_default_sm2_keymgmt().free(keydata); }
static int uadk_keymgmt_sm2_get_params(void *key, OSSL_PARAM params[]) { - if (!get_default_keymgmt().get_params) { + if (!get_default_sm2_keymgmt().get_params) { fprintf(stderr, "failed to get keymgmt get_params function\n"); return UADK_P_FAIL; }
- return get_default_keymgmt().get_params(key, params); + return get_default_sm2_keymgmt().get_params(key, params); }
static const OSSL_PARAM *uadk_keymgmt_sm2_gettable_params(void *provctx) { - if (!get_default_keymgmt().gettable_params) { + if (!get_default_sm2_keymgmt().gettable_params) { fprintf(stderr, "failed to get keymgmt gettable_params function\n"); return NULL; }
- return get_default_keymgmt().gettable_params(provctx); + return get_default_sm2_keymgmt().gettable_params(provctx); }
static int uadk_keymgmt_sm2_set_params(void *key, const OSSL_PARAM params[]) { - if (!get_default_keymgmt().set_params) { + if (!get_default_sm2_keymgmt().set_params) { fprintf(stderr, "failed to get keymgmt set_params function\n"); return UADK_P_FAIL; }
- return get_default_keymgmt().set_params(key, params); + return get_default_sm2_keymgmt().set_params(key, params); }
static int uadk_keymgmt_sm2_gen_set_template(void *genctx, void *templates) { - if (!get_default_keymgmt().gen_set_template) { + if (!get_default_sm2_keymgmt().gen_set_template) { fprintf(stderr, "failed to get keymgmt gen_set_template function\n"); return UADK_P_FAIL; }
- return get_default_keymgmt().gen_set_template(genctx, templates); + return get_default_sm2_keymgmt().gen_set_template(genctx, templates); }
static void uadk_keymgmt_sm2_gen_cleanup(void *genctx) { - if (!get_default_keymgmt().gen_cleanup) { + if (!get_default_sm2_keymgmt().gen_cleanup) { fprintf(stderr, "failed to get keymgmt gen_cleanup function\n"); return; }
- get_default_keymgmt().gen_cleanup(genctx); + get_default_sm2_keymgmt().gen_cleanup(genctx); }
static void *uadk_keymgmt_sm2_load(const void *reference, size_t reference_sz) { - if (!get_default_keymgmt().load) { + if (!get_default_sm2_keymgmt().load) { fprintf(stderr, "failed to get keymgmt load function\n"); return NULL; }
- return get_default_keymgmt().load(reference, reference_sz); + return get_default_sm2_keymgmt().load(reference, reference_sz); }
static int uadk_keymgmt_sm2_validate(const void *keydata, int selection, int checktype) { - if (!get_default_keymgmt().validate) { + if (!get_default_sm2_keymgmt().validate) { fprintf(stderr, "failed to get keymgmt validate function\n"); return UADK_P_FAIL; }
- return get_default_keymgmt().validate(keydata, selection, checktype); + return get_default_sm2_keymgmt().validate(keydata, selection, checktype); }
static int uadk_keymgmt_sm2_match(const void *keydata1, const void *keydata2, int selection) { - if (!get_default_keymgmt().match) { + if (!get_default_sm2_keymgmt().match) { fprintf(stderr, "failed to get keymgmt validate function\n"); return UADK_P_FAIL; }
- return get_default_keymgmt().match(keydata1, keydata2, selection); + return get_default_sm2_keymgmt().match(keydata1, keydata2, selection); }
/** @@ -321,12 +320,12 @@ static int uadk_keymgmt_sm2_match(const void *keydata1, const void *keydata2, in */ static int uadk_keymgmt_sm2_has(const void *keydata, int selection) { - if (!get_default_keymgmt().has) { + if (!get_default_sm2_keymgmt().has) { fprintf(stderr, "failed to get keymgmt has function\n"); return UADK_P_FAIL; }
- return get_default_keymgmt().has(keydata, selection); + return get_default_sm2_keymgmt().has(keydata, selection); }
/** @@ -339,12 +338,12 @@ static int uadk_keymgmt_sm2_has(const void *keydata, int selection) */ static int uadk_keymgmt_sm2_import(void *keydata, int selection, const OSSL_PARAM params[]) { - if (!get_default_keymgmt().import) { + if (!get_default_sm2_keymgmt().import) { fprintf(stderr, "failed to get keymgmt import function\n"); return UADK_P_FAIL; }
- return get_default_keymgmt().import(keydata, selection, params); + return get_default_sm2_keymgmt().import(keydata, selection, params); }
/** @@ -355,43 +354,43 @@ static int uadk_keymgmt_sm2_import(void *keydata, int selection, const OSSL_PARA */ static const OSSL_PARAM *uadk_keymgmt_sm2_import_types(int selection) { - if (!get_default_keymgmt().import_types) { + if (!get_default_sm2_keymgmt().import_types) { fprintf(stderr, "failed to get keymgmt import_types function\n"); return NULL; }
- return get_default_keymgmt().import_types(selection); + return get_default_sm2_keymgmt().import_types(selection); }
static int uadk_keymgmt_sm2_export(void *keydata, int selection, OSSL_CALLBACK *param_callback, void *cbarg) { - if (!get_default_keymgmt().export_fun) { + if (!get_default_sm2_keymgmt().export_fun) { fprintf(stderr, "failed to get keymgmt export function\n"); return UADK_P_FAIL; }
- return get_default_keymgmt().export_fun(keydata, selection, param_callback, cbarg); + return get_default_sm2_keymgmt().export_fun(keydata, selection, param_callback, cbarg); }
static const OSSL_PARAM *uadk_keymgmt_sm2_export_types(int selection) { - if (!get_default_keymgmt().export_types) { + if (!get_default_sm2_keymgmt().export_types) { fprintf(stderr, "failed to get keymgmt export_types function\n"); return NULL; }
- return get_default_keymgmt().export_types(selection); + return get_default_sm2_keymgmt().export_types(selection); }
static void *uadk_keymgmt_sm2_dup(const void *keydata_from, int selection) { - if (!get_default_keymgmt().dup) { + if (!get_default_sm2_keymgmt().dup) { fprintf(stderr, "failed to get keymgmt dup function\n"); return NULL; }
- return get_default_keymgmt().dup(keydata_from, selection); + return get_default_sm2_keymgmt().dup(keydata_from, selection); }
/** @@ -405,12 +404,12 @@ static void *uadk_keymgmt_sm2_dup(const void *keydata_from, int selection) static void *uadk_keymgmt_sm2_gen_init(void *provctx, int selection, const OSSL_PARAM params[]) { - if (!get_default_keymgmt().gen_init) { + if (!get_default_sm2_keymgmt().gen_init) { fprintf(stderr, "failed to get keymgmt gen_init function\n"); return NULL; }
- return get_default_keymgmt().gen_init(provctx, selection, params); + return get_default_sm2_keymgmt().gen_init(provctx, selection, params); }
/** @@ -422,22 +421,22 @@ static void *uadk_keymgmt_sm2_gen_init(void *provctx, int selection, */ static int uadk_keymgmt_sm2_gen_set_params(void *genctx, const OSSL_PARAM params[]) { - if (!get_default_keymgmt().gen_set_params) { + if (!get_default_sm2_keymgmt().gen_set_params) { fprintf(stderr, "failed to get keymgmt gen_set_params function\n"); return UADK_P_FAIL; }
- return get_default_keymgmt().gen_set_params(genctx, params); + return get_default_sm2_keymgmt().gen_set_params(genctx, params); }
static const OSSL_PARAM *uadk_keymgmt_sm2_settable_params(ossl_unused void *provctx) { - if (!get_default_keymgmt().settable_params) { + if (!get_default_sm2_keymgmt().settable_params) { fprintf(stderr, "failed to get keymgmt settable_params function\n"); return NULL; }
- return get_default_keymgmt().settable_params(provctx); + return get_default_sm2_keymgmt().settable_params(provctx); }
/** @@ -450,12 +449,12 @@ static const OSSL_PARAM *uadk_keymgmt_sm2_settable_params(ossl_unused void *prov static const OSSL_PARAM *uadk_keymgmt_sm2_gen_settable_params(ossl_unused void *genctx, ossl_unused void *provctx) { - if (!get_default_keymgmt().gen_settable_params) { + if (!get_default_sm2_keymgmt().gen_settable_params) { fprintf(stderr, "failed to get keymgmt gen_settable_params function\n"); return NULL; }
- return get_default_keymgmt().gen_settable_params(genctx, provctx); + return get_default_sm2_keymgmt().gen_settable_params(genctx, provctx); }
static void uadk_prov_sm2_mutex_infork(void)
From: Qi Tao taoqi10@huawei.com
Can not convert ‘size_t*’ {‘long unsigned int*’} to ‘int*’, which may cause data loss or other problems.
Signed-off-by: Qi Tao taoqi10@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- src/uadk_prov_cipher.c | 24 ++++++++++++------------ src/uadk_prov_digest.c | 3 +++ src/uadk_prov_init.c | 4 ---- 3 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/src/uadk_prov_cipher.c b/src/uadk_prov_cipher.c index 7847c12..92a9e79 100644 --- a/src/uadk_prov_cipher.c +++ b/src/uadk_prov_cipher.c @@ -329,9 +329,9 @@ static int uadk_prov_cipher_soft_work(struct cipher_priv_ctx *priv, unsigned cha }
static int uadk_prov_cipher_soft_final(struct cipher_priv_ctx *priv, unsigned char *out, - size_t *outl) + int *outl) { - size_t sw_final_len = 0; + int sw_final_len = 0;
if (priv->sw_cipher == NULL) return UADK_E_FAIL; @@ -684,7 +684,7 @@ static int ossl_cipher_unpadblock(unsigned char *buf, size_t *buflen, size_t blo }
static int uadk_prov_hw_cipher(struct cipher_priv_ctx *priv, unsigned char *out, - size_t *outl, size_t outsize, + int *outl, size_t outsize, const unsigned char *in, size_t inlen) { size_t blksz = priv->blksize; @@ -732,7 +732,7 @@ static int uadk_prov_hw_cipher(struct cipher_priv_ctx *priv, unsigned char *out, }
static int uadk_prov_do_cipher(struct cipher_priv_ctx *priv, unsigned char *out, - size_t *outl, size_t outsize, + int *outl, size_t outsize, const unsigned char *in, size_t inlen) { size_t blksz = priv->blksize; @@ -834,7 +834,7 @@ static OSSL_FUNC_cipher_gettable_ctx_params_fn uadk_prov_cipher_gettable_ctx_par static OSSL_FUNC_cipher_set_ctx_params_fn uadk_prov_cipher_set_ctx_params; static OSSL_FUNC_cipher_settable_ctx_params_fn uadk_prov_cipher_settable_ctx_params;
-static int uadk_prov_cipher_cipher(void *vctx, unsigned char *out, size_t *outl, +static int uadk_prov_cipher_cipher(void *vctx, unsigned char *out, int *outl, size_t outsize, const unsigned char *in, size_t inl) { @@ -864,9 +864,9 @@ static int uadk_prov_cipher_cipher(void *vctx, unsigned char *out, size_t *outl, }
static int uadk_prov_cipher_block_encrypto(struct cipher_priv_ctx *priv, - unsigned char *out, size_t *outl, size_t outsize) + unsigned char *out, int *outl, size_t outsize) { - size_t blksz = priv->blksize; + int blksz = priv->blksize; int ret;
if (priv->pad) { @@ -896,7 +896,7 @@ static int uadk_prov_cipher_block_encrypto(struct cipher_priv_ctx *priv, }
static int uadk_prov_cipher_block_decrypto(struct cipher_priv_ctx *priv, - unsigned char *out, size_t *outl, size_t outsize) + unsigned char *out, int *outl, size_t outsize) { size_t blksz = priv->blksize; int ret; @@ -935,7 +935,7 @@ static int uadk_prov_cipher_block_decrypto(struct cipher_priv_ctx *priv, }
static int uadk_prov_cipher_block_final(void *vctx, unsigned char *out, - size_t *outl, size_t outsize) + int *outl, size_t outsize) { struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; int ret; @@ -955,7 +955,7 @@ static int uadk_prov_cipher_block_final(void *vctx, unsigned char *out, }
static int uadk_prov_cipher_block_update(void *vctx, unsigned char *out, - size_t *outl, size_t outsize, + int *outl, size_t outsize, const unsigned char *in, size_t inl) { struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; @@ -977,7 +977,7 @@ static int uadk_prov_cipher_block_update(void *vctx, unsigned char *out, }
static int uadk_prov_cipher_stream_update(void *vctx, unsigned char *out, - size_t *outl, size_t outsize, + int *outl, size_t outsize, const unsigned char *in, size_t inl) { struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx; @@ -1027,7 +1027,7 @@ do_soft: }
static int uadk_prov_cipher_stream_final(void *vctx, unsigned char *out, - size_t *outl, size_t outsize) + int *outl, size_t outsize) { struct cipher_priv_ctx *priv = (struct cipher_priv_ctx *)vctx;
diff --git a/src/uadk_prov_digest.c b/src/uadk_prov_digest.c index eddca1a..c442700 100644 --- a/src/uadk_prov_digest.c +++ b/src/uadk_prov_digest.c @@ -630,6 +630,9 @@ static void uadk_digest_cleanup(struct digest_priv_ctx *priv)
if (priv->data) OPENSSL_free(priv->data); + + if (priv->soft_ctx) + OPENSSL_free(priv->soft_ctx); }
/* some params related code is copied from OpenSSL v3.0 prov/digestcommon.h */ diff --git a/src/uadk_prov_init.c b/src/uadk_prov_init.c index d4adb20..010c87b 100644 --- a/src/uadk_prov_init.c +++ b/src/uadk_prov_init.c @@ -39,10 +39,6 @@ static OSSL_FUNC_core_gettable_params_fn *c_gettable_params; static OSSL_FUNC_core_get_params_fn *c_get_params; static OSSL_FUNC_core_get_libctx_fn *c_get_libctx;
-/* Functions provided by the core */ -static OSSL_FUNC_core_get_params_fn *c_get_params; -static OSSL_FUNC_core_get_libctx_fn *c_get_libctx; - struct uadk_provider_params { char *enable_sw_offload; } uadk_params;