Skip to content

Commit eb113e2

Browse files
committed
provider: Add support for OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ on import
When importing a private RSA key from params, allow that only private CRT key components OSSL_PARAM_RSA_FACTOR1, OSSL_PARAM_RSA_FACTOR2, as well as the public key components OSSL_PARAM_RSA_N and OSSL_PKEY_PARAM_RSA_E are available in the params, when also OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ with a nonzero value is contained. In this case the other CRT components are calculated to form a complete CRT key. OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ is available since OpenSSL 3.3. Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
1 parent 6eb94a5 commit eb113e2

File tree

1 file changed

+125
-35
lines changed

1 file changed

+125
-35
lines changed

src/provider/rsa_keymgmt.c

Lines changed: 125 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ static OSSL_FUNC_keymgmt_import_types_fn ibmca_keymgmt_rsa_pss_import_types;
7575
static void ibmca_keymgmt_rsa_free_cb(struct ibmca_key *key);
7676
static int ibmca_keymgmt_rsa_dup_cb(const struct ibmca_key *key,
7777
struct ibmca_key *new_key);
78+
static int ibmca_keymgmt_rsa_calc_priv_d(const struct ibmca_prov_ctx *provctx,
79+
BIGNUM *n, BIGNUM *e,
80+
BIGNUM *p, BIGNUM *q,
81+
BIGNUM **d);
7882

7983
static int ibmca_keymgmt_rsa_pss_parms_from_data(
8084
const struct ibmca_prov_ctx *provctx,
@@ -257,72 +261,155 @@ static int ibmca_keymgmt_rsa_pub_key_to_data(
257261
return 1;
258262
}
259263

264+
static int ibmca_keymgmt_rsa_derive_crt_from_pq(
265+
const struct ibmca_prov_ctx *provctx,
266+
BIGNUM *n, BIGNUM *e, BIGNUM *p,
267+
BIGNUM *q, BIGNUM *dp, BIGNUM *dq,
268+
BIGNUM *qinv)
269+
{
270+
BIGNUM *d = NULL, *p1 = NULL, *q1 = NULL;
271+
BN_CTX *ctx = NULL;
272+
int rc = 0;
273+
274+
ctx = BN_CTX_secure_new();
275+
if (ctx == NULL) {
276+
put_error_ctx(provctx, IBMCA_ERR_MALLOC_FAILED,
277+
"BN_CTX_secure_new failed");
278+
goto out;
279+
}
280+
281+
p1 = BN_CTX_get(ctx);
282+
q1 = BN_CTX_get(ctx);
283+
if (p1 == NULL || q1 == NULL) {
284+
put_error_ctx(provctx, IBMCA_ERR_MALLOC_FAILED, "BN_CTX_get failed");
285+
goto out;
286+
}
287+
288+
BN_set_flags(p1, BN_FLG_CONSTTIME);
289+
BN_set_flags(q1, BN_FLG_CONSTTIME);
290+
291+
if (!BN_sub(p1, p, BN_value_one()) || /* p-1 */
292+
!BN_sub(q1, q, BN_value_one())) { /* q-1 */
293+
put_error_ctx(provctx, IBMCA_ERR_MALLOC_FAILED, "BN_sub failed");
294+
goto out;
295+
}
296+
297+
BN_set_flags(dp, BN_FLG_CONSTTIME);
298+
BN_set_flags(dq, BN_FLG_CONSTTIME);
299+
BN_set_flags(qinv, BN_FLG_CONSTTIME);
300+
301+
rc = ibmca_keymgmt_rsa_calc_priv_d(provctx, n, e, p, q, &d);
302+
if (rc != 1)
303+
goto out;
304+
305+
rc = 0;
306+
307+
/*
308+
* See SP800-56Br1 6.3.1.3 rsakpg1 - crt (Step 5)
309+
*
310+
* (Step 5a) dP = d mod (p-1)
311+
*/
312+
if (!BN_mod(dp, d, p1, ctx)) {
313+
put_error_ctx(provctx, IBMCA_ERR_INTERNAL_ERROR, "BN_mod failed");
314+
goto out;
315+
}
316+
317+
/* (Step 5b) dQ = d mod (q-1) */
318+
if (!BN_mod(dq, d, q1, ctx)) {
319+
put_error_ctx(provctx, IBMCA_ERR_INTERNAL_ERROR, "BN_mod failed");
320+
goto out;
321+
}
322+
323+
/* (Step 5c) qInv = (inverse of q) mod p */
324+
if (BN_mod_inverse(qinv, q, p, ctx) == NULL) {
325+
put_error_ctx(provctx, IBMCA_ERR_INTERNAL_ERROR,
326+
"BN_mod_inverse failed");
327+
goto out;
328+
}
329+
330+
rc = 1;
331+
332+
out:
333+
BN_CTX_free(ctx);
334+
BN_free(d);
335+
336+
return rc;
337+
}
338+
260339
static int ibmca_keymgmt_rsa_priv_crt_key_from_data(
261340
const struct ibmca_prov_ctx *provctx,
262-
const OSSL_PARAM params[], BIGNUM **p,
263-
BIGNUM **q, BIGNUM **dp,
264-
BIGNUM **dq, BIGNUM **qinv)
341+
const OSSL_PARAM params[],
342+
BIGNUM *n, BIGNUM *e,
343+
BIGNUM **p, BIGNUM **q,
344+
BIGNUM **dp, BIGNUM **dq, BIGNUM **qinv)
265345
{
266-
int rc;
346+
int rc, derive_from_pq = 0;
267347

268-
/* OSSL_PKEY_PARAM_RSA_FACTOR1 */
269348
*p = BN_secure_new();
270-
if (*p == NULL) {
349+
*q = BN_secure_new();
350+
*dp = BN_secure_new();
351+
*dq = BN_secure_new();
352+
*qinv = BN_secure_new();
353+
if (*p == NULL || *q == NULL || *dp == NULL || *dp == NULL ||
354+
*qinv == NULL) {
271355
put_error_ctx(provctx, IBMCA_ERR_MALLOC_FAILED, "BN_secure_new failed");
272356
goto error;
273357
}
358+
359+
/* OSSL_PKEY_PARAM_RSA_FACTOR1 */
274360
rc = ibmca_param_get_bn(provctx, params, OSSL_PKEY_PARAM_RSA_FACTOR1, p);
275361
if (rc <= 0)
276362
goto error;
277363

278364
/* OSSL_PKEY_PARAM_RSA_FACTOR2 */
279-
*q = BN_secure_new();
280-
if (*q == NULL) {
281-
put_error_ctx(provctx, IBMCA_ERR_MALLOC_FAILED, "BN_secure_new failed");
282-
goto error;
283-
}
284365
rc = ibmca_param_get_bn(provctx, params, OSSL_PKEY_PARAM_RSA_FACTOR2, q);
285366
if (rc <= 0)
286367
goto error;
287368

288369
/* OSSL_PKEY_PARAM_RSA_EXPONENT1 */
289-
*dp = BN_secure_new();
290-
if (*dp == NULL) {
291-
put_error_ctx(provctx, IBMCA_ERR_MALLOC_FAILED, "BN_secure_new failed");
292-
goto error;
293-
}
294370
rc = ibmca_param_get_bn(provctx, params, OSSL_PKEY_PARAM_RSA_EXPONENT1,
295371
dp);
296372
if (rc <= 0)
297-
goto error;
373+
goto check_from_pq;
298374

299375
/* OSSL_PKEY_PARAM_RSA_EXPONENT2 */
300-
*dq = BN_secure_new();
301-
if (*dq == NULL) {
302-
put_error_ctx(provctx, IBMCA_ERR_MALLOC_FAILED, "BN_secure_new failed");
303-
goto error;
304-
}
305376
rc = ibmca_param_get_bn(provctx, params, OSSL_PKEY_PARAM_RSA_EXPONENT2,
306377
dq);
307378
if (rc <= 0)
308-
goto error;
379+
goto check_from_pq;
309380

310381
/* OSSL_PKEY_PARAM_RSA_COEFFICIENT1 */
311-
*qinv = BN_secure_new();
312-
if (*qinv == NULL) {
313-
put_error_ctx(provctx, IBMCA_ERR_MALLOC_FAILED, "BN_secure_new failed");
314-
goto error;
315-
}
316382
rc = ibmca_param_get_bn(provctx, params, OSSL_PKEY_PARAM_RSA_COEFFICIENT1,
317383
qinv);
318384
if (rc <= 0)
319-
goto error;
385+
goto check_from_pq;
320386

321387
return 1;
322388

389+
check_from_pq:
390+
#ifdef OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ
391+
/* OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ */
392+
rc = ibmca_param_get_int(provctx, params,
393+
OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ,
394+
&derive_from_pq);
395+
if (rc <= 0)
396+
goto error;
397+
#endif
398+
399+
if (derive_from_pq) {
400+
rc = ibmca_keymgmt_rsa_derive_crt_from_pq(provctx, n, e, *p, *q,
401+
*dp, *dq, *qinv);
402+
if (rc != 1)
403+
goto error;
404+
405+
return 1;
406+
}
407+
323408
error:
324409
BN_clear_free(*p);
325410
*p = NULL;
411+
BN_clear_free(*q);
412+
*q = NULL;
326413
BN_clear_free(*dp);
327414
*dp = NULL;
328415
BN_clear_free(*dq);
@@ -1496,8 +1583,9 @@ int ibmca_keymgmt_rsa_priv_me_as_bn(struct ibmca_key *key, BIGNUM **d)
14961583
return 0;
14971584
}
14981585

1499-
static int ibmca_keymgmt_rsa_calc_priv_d(struct ibmca_key *key, BIGNUM *n,
1500-
BIGNUM *e, BIGNUM *p, BIGNUM *q,
1586+
static int ibmca_keymgmt_rsa_calc_priv_d(const struct ibmca_prov_ctx *provctx,
1587+
BIGNUM *n, BIGNUM *e,
1588+
BIGNUM *p, BIGNUM *q,
15011589
BIGNUM **d)
15021590
{
15031591
BN_CTX *bn_ctx;
@@ -1514,7 +1602,7 @@ static int ibmca_keymgmt_rsa_calc_priv_d(struct ibmca_key *key, BIGNUM *n,
15141602
BN_sub(*d, *d, q) == 0 ||
15151603
BN_add_word(*d, 1) == 0 ||
15161604
BN_mod_inverse(*d, e, *d, bn_ctx) == NULL) {
1517-
put_error_key(key, IBMCA_ERR_INTERNAL_ERROR,
1605+
put_error_ctx(provctx, IBMCA_ERR_INTERNAL_ERROR,
15181606
"Failed to calculate private key part d");
15191607
BN_CTX_free(bn_ctx);
15201608
BN_clear_free(*d);
@@ -1609,7 +1697,7 @@ static int ibmca_keymgmt_rsa_get_params(void *vkey, OSSL_PARAM params[])
16091697
/* CRT format */
16101698
rc = ibmca_keymgmt_rsa_priv_me_as_bn(key, &d);
16111699
if (rc == 0) {
1612-
rc = ibmca_keymgmt_rsa_calc_priv_d(key, n, e, p, q, &d);
1700+
rc = ibmca_keymgmt_rsa_calc_priv_d(key->provctx, n, e, p, q, &d);
16131701
if (rc == 0)
16141702
goto out;
16151703
}
@@ -1868,7 +1956,8 @@ int ibmca_keymgmt_rsa_export(void *vkey, int selection,
18681956
/* CRT format */
18691957
rc = ibmca_keymgmt_rsa_priv_me_as_bn(key, &d);
18701958
if (rc == 0) {
1871-
rc = ibmca_keymgmt_rsa_calc_priv_d(key, n, e, p, q, &d);
1959+
rc = ibmca_keymgmt_rsa_calc_priv_d(key->provctx, n, e, p, q,
1960+
&d);
18721961
if (rc == 0)
18731962
goto error;
18741963
}
@@ -1989,6 +2078,7 @@ int ibmca_keymgmt_rsa_import(void *vkey, int selection,
19892078
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
19902079
/* Import private key parts */
19912080
rc = ibmca_keymgmt_rsa_priv_crt_key_from_data(key->provctx, params,
2081+
n, e,
19922082
&p, &q, &dp, &dq, &qinv);
19932083
if (rc == 1) {
19942084
/* CRT components */
@@ -2127,7 +2217,7 @@ int ibmca_keymgmt_rsa_derive_kdk(struct ibmca_key *key,
21272217
if (rc == 0)
21282218
goto out;
21292219

2130-
rc = ibmca_keymgmt_rsa_calc_priv_d(key, n, e, p, q, &d);
2220+
rc = ibmca_keymgmt_rsa_calc_priv_d(key->provctx, n, e, p, q, &d);
21312221
if (rc == 0)
21322222
goto out;
21332223
}

0 commit comments

Comments
 (0)