1*b077aed3SPierre Pronchery /*
2*b077aed3SPierre Pronchery * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved.
3*b077aed3SPierre Pronchery *
4*b077aed3SPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use
5*b077aed3SPierre Pronchery * this file except in compliance with the License. You can obtain a copy
6*b077aed3SPierre Pronchery * in the file LICENSE in the source distribution or at
7*b077aed3SPierre Pronchery * https://www.openssl.org/source/license.html
8*b077aed3SPierre Pronchery */
9*b077aed3SPierre Pronchery
10*b077aed3SPierre Pronchery /*
11*b077aed3SPierre Pronchery * RSA low level APIs are deprecated for public use, but still ok for
12*b077aed3SPierre Pronchery * internal use.
13*b077aed3SPierre Pronchery */
14*b077aed3SPierre Pronchery #include "internal/deprecated.h"
15*b077aed3SPierre Pronchery #include "internal/nelem.h"
16*b077aed3SPierre Pronchery
17*b077aed3SPierre Pronchery #include <openssl/crypto.h>
18*b077aed3SPierre Pronchery #include <openssl/evp.h>
19*b077aed3SPierre Pronchery #include <openssl/core_dispatch.h>
20*b077aed3SPierre Pronchery #include <openssl/core_names.h>
21*b077aed3SPierre Pronchery #include <openssl/rsa.h>
22*b077aed3SPierre Pronchery #include <openssl/params.h>
23*b077aed3SPierre Pronchery #include <openssl/err.h>
24*b077aed3SPierre Pronchery #include "crypto/rsa.h"
25*b077aed3SPierre Pronchery #include <openssl/proverr.h>
26*b077aed3SPierre Pronchery #include "prov/provider_ctx.h"
27*b077aed3SPierre Pronchery #include "prov/implementations.h"
28*b077aed3SPierre Pronchery #include "prov/securitycheck.h"
29*b077aed3SPierre Pronchery
30*b077aed3SPierre Pronchery static OSSL_FUNC_kem_newctx_fn rsakem_newctx;
31*b077aed3SPierre Pronchery static OSSL_FUNC_kem_encapsulate_init_fn rsakem_encapsulate_init;
32*b077aed3SPierre Pronchery static OSSL_FUNC_kem_encapsulate_fn rsakem_generate;
33*b077aed3SPierre Pronchery static OSSL_FUNC_kem_decapsulate_init_fn rsakem_decapsulate_init;
34*b077aed3SPierre Pronchery static OSSL_FUNC_kem_decapsulate_fn rsakem_recover;
35*b077aed3SPierre Pronchery static OSSL_FUNC_kem_freectx_fn rsakem_freectx;
36*b077aed3SPierre Pronchery static OSSL_FUNC_kem_dupctx_fn rsakem_dupctx;
37*b077aed3SPierre Pronchery static OSSL_FUNC_kem_get_ctx_params_fn rsakem_get_ctx_params;
38*b077aed3SPierre Pronchery static OSSL_FUNC_kem_gettable_ctx_params_fn rsakem_gettable_ctx_params;
39*b077aed3SPierre Pronchery static OSSL_FUNC_kem_set_ctx_params_fn rsakem_set_ctx_params;
40*b077aed3SPierre Pronchery static OSSL_FUNC_kem_settable_ctx_params_fn rsakem_settable_ctx_params;
41*b077aed3SPierre Pronchery
42*b077aed3SPierre Pronchery /*
43*b077aed3SPierre Pronchery * Only the KEM for RSASVE as defined in SP800-56b r2 is implemented
44*b077aed3SPierre Pronchery * currently.
45*b077aed3SPierre Pronchery */
46*b077aed3SPierre Pronchery #define KEM_OP_UNDEFINED -1
47*b077aed3SPierre Pronchery #define KEM_OP_RSASVE 0
48*b077aed3SPierre Pronchery
49*b077aed3SPierre Pronchery /*
50*b077aed3SPierre Pronchery * What's passed as an actual key is defined by the KEYMGMT interface.
51*b077aed3SPierre Pronchery * We happen to know that our KEYMGMT simply passes RSA structures, so
52*b077aed3SPierre Pronchery * we use that here too.
53*b077aed3SPierre Pronchery */
54*b077aed3SPierre Pronchery typedef struct {
55*b077aed3SPierre Pronchery OSSL_LIB_CTX *libctx;
56*b077aed3SPierre Pronchery RSA *rsa;
57*b077aed3SPierre Pronchery int op;
58*b077aed3SPierre Pronchery } PROV_RSA_CTX;
59*b077aed3SPierre Pronchery
60*b077aed3SPierre Pronchery static const OSSL_ITEM rsakem_opname_id_map[] = {
61*b077aed3SPierre Pronchery { KEM_OP_RSASVE, OSSL_KEM_PARAM_OPERATION_RSASVE },
62*b077aed3SPierre Pronchery };
63*b077aed3SPierre Pronchery
name2id(const char * name,const OSSL_ITEM * map,size_t sz)64*b077aed3SPierre Pronchery static int name2id(const char *name, const OSSL_ITEM *map, size_t sz)
65*b077aed3SPierre Pronchery {
66*b077aed3SPierre Pronchery size_t i;
67*b077aed3SPierre Pronchery
68*b077aed3SPierre Pronchery if (name == NULL)
69*b077aed3SPierre Pronchery return -1;
70*b077aed3SPierre Pronchery
71*b077aed3SPierre Pronchery for (i = 0; i < sz; ++i) {
72*b077aed3SPierre Pronchery if (OPENSSL_strcasecmp(map[i].ptr, name) == 0)
73*b077aed3SPierre Pronchery return map[i].id;
74*b077aed3SPierre Pronchery }
75*b077aed3SPierre Pronchery return -1;
76*b077aed3SPierre Pronchery }
77*b077aed3SPierre Pronchery
rsakem_opname2id(const char * name)78*b077aed3SPierre Pronchery static int rsakem_opname2id(const char *name)
79*b077aed3SPierre Pronchery {
80*b077aed3SPierre Pronchery return name2id(name, rsakem_opname_id_map, OSSL_NELEM(rsakem_opname_id_map));
81*b077aed3SPierre Pronchery }
82*b077aed3SPierre Pronchery
rsakem_newctx(void * provctx)83*b077aed3SPierre Pronchery static void *rsakem_newctx(void *provctx)
84*b077aed3SPierre Pronchery {
85*b077aed3SPierre Pronchery PROV_RSA_CTX *prsactx = OPENSSL_zalloc(sizeof(PROV_RSA_CTX));
86*b077aed3SPierre Pronchery
87*b077aed3SPierre Pronchery if (prsactx == NULL)
88*b077aed3SPierre Pronchery return NULL;
89*b077aed3SPierre Pronchery prsactx->libctx = PROV_LIBCTX_OF(provctx);
90*b077aed3SPierre Pronchery prsactx->op = KEM_OP_UNDEFINED;
91*b077aed3SPierre Pronchery
92*b077aed3SPierre Pronchery return prsactx;
93*b077aed3SPierre Pronchery }
94*b077aed3SPierre Pronchery
rsakem_freectx(void * vprsactx)95*b077aed3SPierre Pronchery static void rsakem_freectx(void *vprsactx)
96*b077aed3SPierre Pronchery {
97*b077aed3SPierre Pronchery PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
98*b077aed3SPierre Pronchery
99*b077aed3SPierre Pronchery RSA_free(prsactx->rsa);
100*b077aed3SPierre Pronchery OPENSSL_free(prsactx);
101*b077aed3SPierre Pronchery }
102*b077aed3SPierre Pronchery
rsakem_dupctx(void * vprsactx)103*b077aed3SPierre Pronchery static void *rsakem_dupctx(void *vprsactx)
104*b077aed3SPierre Pronchery {
105*b077aed3SPierre Pronchery PROV_RSA_CTX *srcctx = (PROV_RSA_CTX *)vprsactx;
106*b077aed3SPierre Pronchery PROV_RSA_CTX *dstctx;
107*b077aed3SPierre Pronchery
108*b077aed3SPierre Pronchery dstctx = OPENSSL_zalloc(sizeof(*srcctx));
109*b077aed3SPierre Pronchery if (dstctx == NULL)
110*b077aed3SPierre Pronchery return NULL;
111*b077aed3SPierre Pronchery
112*b077aed3SPierre Pronchery *dstctx = *srcctx;
113*b077aed3SPierre Pronchery if (dstctx->rsa != NULL && !RSA_up_ref(dstctx->rsa)) {
114*b077aed3SPierre Pronchery OPENSSL_free(dstctx);
115*b077aed3SPierre Pronchery return NULL;
116*b077aed3SPierre Pronchery }
117*b077aed3SPierre Pronchery return dstctx;
118*b077aed3SPierre Pronchery }
119*b077aed3SPierre Pronchery
rsakem_init(void * vprsactx,void * vrsa,const OSSL_PARAM params[],int operation)120*b077aed3SPierre Pronchery static int rsakem_init(void *vprsactx, void *vrsa,
121*b077aed3SPierre Pronchery const OSSL_PARAM params[], int operation)
122*b077aed3SPierre Pronchery {
123*b077aed3SPierre Pronchery PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
124*b077aed3SPierre Pronchery
125*b077aed3SPierre Pronchery if (prsactx == NULL || vrsa == NULL)
126*b077aed3SPierre Pronchery return 0;
127*b077aed3SPierre Pronchery
128*b077aed3SPierre Pronchery if (!ossl_rsa_check_key(prsactx->libctx, vrsa, operation))
129*b077aed3SPierre Pronchery return 0;
130*b077aed3SPierre Pronchery
131*b077aed3SPierre Pronchery if (!RSA_up_ref(vrsa))
132*b077aed3SPierre Pronchery return 0;
133*b077aed3SPierre Pronchery RSA_free(prsactx->rsa);
134*b077aed3SPierre Pronchery prsactx->rsa = vrsa;
135*b077aed3SPierre Pronchery
136*b077aed3SPierre Pronchery return rsakem_set_ctx_params(prsactx, params);
137*b077aed3SPierre Pronchery }
138*b077aed3SPierre Pronchery
rsakem_encapsulate_init(void * vprsactx,void * vrsa,const OSSL_PARAM params[])139*b077aed3SPierre Pronchery static int rsakem_encapsulate_init(void *vprsactx, void *vrsa,
140*b077aed3SPierre Pronchery const OSSL_PARAM params[])
141*b077aed3SPierre Pronchery {
142*b077aed3SPierre Pronchery return rsakem_init(vprsactx, vrsa, params, EVP_PKEY_OP_ENCAPSULATE);
143*b077aed3SPierre Pronchery }
144*b077aed3SPierre Pronchery
rsakem_decapsulate_init(void * vprsactx,void * vrsa,const OSSL_PARAM params[])145*b077aed3SPierre Pronchery static int rsakem_decapsulate_init(void *vprsactx, void *vrsa,
146*b077aed3SPierre Pronchery const OSSL_PARAM params[])
147*b077aed3SPierre Pronchery {
148*b077aed3SPierre Pronchery return rsakem_init(vprsactx, vrsa, params, EVP_PKEY_OP_DECAPSULATE);
149*b077aed3SPierre Pronchery }
150*b077aed3SPierre Pronchery
rsakem_get_ctx_params(void * vprsactx,OSSL_PARAM * params)151*b077aed3SPierre Pronchery static int rsakem_get_ctx_params(void *vprsactx, OSSL_PARAM *params)
152*b077aed3SPierre Pronchery {
153*b077aed3SPierre Pronchery PROV_RSA_CTX *ctx = (PROV_RSA_CTX *)vprsactx;
154*b077aed3SPierre Pronchery
155*b077aed3SPierre Pronchery return ctx != NULL;
156*b077aed3SPierre Pronchery }
157*b077aed3SPierre Pronchery
158*b077aed3SPierre Pronchery static const OSSL_PARAM known_gettable_rsakem_ctx_params[] = {
159*b077aed3SPierre Pronchery OSSL_PARAM_END
160*b077aed3SPierre Pronchery };
161*b077aed3SPierre Pronchery
rsakem_gettable_ctx_params(ossl_unused void * vprsactx,ossl_unused void * provctx)162*b077aed3SPierre Pronchery static const OSSL_PARAM *rsakem_gettable_ctx_params(ossl_unused void *vprsactx,
163*b077aed3SPierre Pronchery ossl_unused void *provctx)
164*b077aed3SPierre Pronchery {
165*b077aed3SPierre Pronchery return known_gettable_rsakem_ctx_params;
166*b077aed3SPierre Pronchery }
167*b077aed3SPierre Pronchery
rsakem_set_ctx_params(void * vprsactx,const OSSL_PARAM params[])168*b077aed3SPierre Pronchery static int rsakem_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
169*b077aed3SPierre Pronchery {
170*b077aed3SPierre Pronchery PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
171*b077aed3SPierre Pronchery const OSSL_PARAM *p;
172*b077aed3SPierre Pronchery int op;
173*b077aed3SPierre Pronchery
174*b077aed3SPierre Pronchery if (prsactx == NULL)
175*b077aed3SPierre Pronchery return 0;
176*b077aed3SPierre Pronchery if (params == NULL)
177*b077aed3SPierre Pronchery return 1;
178*b077aed3SPierre Pronchery
179*b077aed3SPierre Pronchery
180*b077aed3SPierre Pronchery p = OSSL_PARAM_locate_const(params, OSSL_KEM_PARAM_OPERATION);
181*b077aed3SPierre Pronchery if (p != NULL) {
182*b077aed3SPierre Pronchery if (p->data_type != OSSL_PARAM_UTF8_STRING)
183*b077aed3SPierre Pronchery return 0;
184*b077aed3SPierre Pronchery op = rsakem_opname2id(p->data);
185*b077aed3SPierre Pronchery if (op < 0)
186*b077aed3SPierre Pronchery return 0;
187*b077aed3SPierre Pronchery prsactx->op = op;
188*b077aed3SPierre Pronchery }
189*b077aed3SPierre Pronchery return 1;
190*b077aed3SPierre Pronchery }
191*b077aed3SPierre Pronchery
192*b077aed3SPierre Pronchery static const OSSL_PARAM known_settable_rsakem_ctx_params[] = {
193*b077aed3SPierre Pronchery OSSL_PARAM_utf8_string(OSSL_KEM_PARAM_OPERATION, NULL, 0),
194*b077aed3SPierre Pronchery OSSL_PARAM_END
195*b077aed3SPierre Pronchery };
196*b077aed3SPierre Pronchery
rsakem_settable_ctx_params(ossl_unused void * vprsactx,ossl_unused void * provctx)197*b077aed3SPierre Pronchery static const OSSL_PARAM *rsakem_settable_ctx_params(ossl_unused void *vprsactx,
198*b077aed3SPierre Pronchery ossl_unused void *provctx)
199*b077aed3SPierre Pronchery {
200*b077aed3SPierre Pronchery return known_settable_rsakem_ctx_params;
201*b077aed3SPierre Pronchery }
202*b077aed3SPierre Pronchery
203*b077aed3SPierre Pronchery /*
204*b077aed3SPierre Pronchery * NIST.SP.800-56Br2
205*b077aed3SPierre Pronchery * 7.2.1.2 RSASVE Generate Operation (RSASVE.GENERATE).
206*b077aed3SPierre Pronchery *
207*b077aed3SPierre Pronchery * Generate a random in the range 1 < z < (n – 1)
208*b077aed3SPierre Pronchery */
rsasve_gen_rand_bytes(RSA * rsa_pub,unsigned char * out,int outlen)209*b077aed3SPierre Pronchery static int rsasve_gen_rand_bytes(RSA *rsa_pub,
210*b077aed3SPierre Pronchery unsigned char *out, int outlen)
211*b077aed3SPierre Pronchery {
212*b077aed3SPierre Pronchery int ret = 0;
213*b077aed3SPierre Pronchery BN_CTX *bnctx;
214*b077aed3SPierre Pronchery BIGNUM *z, *nminus3;
215*b077aed3SPierre Pronchery
216*b077aed3SPierre Pronchery bnctx = BN_CTX_secure_new_ex(ossl_rsa_get0_libctx(rsa_pub));
217*b077aed3SPierre Pronchery if (bnctx == NULL)
218*b077aed3SPierre Pronchery return 0;
219*b077aed3SPierre Pronchery
220*b077aed3SPierre Pronchery /*
221*b077aed3SPierre Pronchery * Generate a random in the range 1 < z < (n – 1).
222*b077aed3SPierre Pronchery * Since BN_priv_rand_range_ex() returns a value in range 0 <= r < max
223*b077aed3SPierre Pronchery * We can achieve this by adding 2.. but then we need to subtract 3 from
224*b077aed3SPierre Pronchery * the upper bound i.e: 2 + (0 <= r < (n - 3))
225*b077aed3SPierre Pronchery */
226*b077aed3SPierre Pronchery BN_CTX_start(bnctx);
227*b077aed3SPierre Pronchery nminus3 = BN_CTX_get(bnctx);
228*b077aed3SPierre Pronchery z = BN_CTX_get(bnctx);
229*b077aed3SPierre Pronchery ret = (z != NULL
230*b077aed3SPierre Pronchery && (BN_copy(nminus3, RSA_get0_n(rsa_pub)) != NULL)
231*b077aed3SPierre Pronchery && BN_sub_word(nminus3, 3)
232*b077aed3SPierre Pronchery && BN_priv_rand_range_ex(z, nminus3, 0, bnctx)
233*b077aed3SPierre Pronchery && BN_add_word(z, 2)
234*b077aed3SPierre Pronchery && (BN_bn2binpad(z, out, outlen) == outlen));
235*b077aed3SPierre Pronchery BN_CTX_end(bnctx);
236*b077aed3SPierre Pronchery BN_CTX_free(bnctx);
237*b077aed3SPierre Pronchery return ret;
238*b077aed3SPierre Pronchery }
239*b077aed3SPierre Pronchery
240*b077aed3SPierre Pronchery /*
241*b077aed3SPierre Pronchery * NIST.SP.800-56Br2
242*b077aed3SPierre Pronchery * 7.2.1.2 RSASVE Generate Operation (RSASVE.GENERATE).
243*b077aed3SPierre Pronchery */
rsasve_generate(PROV_RSA_CTX * prsactx,unsigned char * out,size_t * outlen,unsigned char * secret,size_t * secretlen)244*b077aed3SPierre Pronchery static int rsasve_generate(PROV_RSA_CTX *prsactx,
245*b077aed3SPierre Pronchery unsigned char *out, size_t *outlen,
246*b077aed3SPierre Pronchery unsigned char *secret, size_t *secretlen)
247*b077aed3SPierre Pronchery {
248*b077aed3SPierre Pronchery int ret;
249*b077aed3SPierre Pronchery size_t nlen;
250*b077aed3SPierre Pronchery
251*b077aed3SPierre Pronchery /* Step (1): nlen = Ceil(len(n)/8) */
252*b077aed3SPierre Pronchery nlen = RSA_size(prsactx->rsa);
253*b077aed3SPierre Pronchery
254*b077aed3SPierre Pronchery if (out == NULL) {
255*b077aed3SPierre Pronchery if (nlen == 0) {
256*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
257*b077aed3SPierre Pronchery return 0;
258*b077aed3SPierre Pronchery }
259*b077aed3SPierre Pronchery if (outlen == NULL && secretlen == NULL)
260*b077aed3SPierre Pronchery return 0;
261*b077aed3SPierre Pronchery if (outlen != NULL)
262*b077aed3SPierre Pronchery *outlen = nlen;
263*b077aed3SPierre Pronchery if (secretlen != NULL)
264*b077aed3SPierre Pronchery *secretlen = nlen;
265*b077aed3SPierre Pronchery return 1;
266*b077aed3SPierre Pronchery }
267*b077aed3SPierre Pronchery /*
268*b077aed3SPierre Pronchery * Step (2): Generate a random byte string z of nlen bytes where
269*b077aed3SPierre Pronchery * 1 < z < n - 1
270*b077aed3SPierre Pronchery */
271*b077aed3SPierre Pronchery if (!rsasve_gen_rand_bytes(prsactx->rsa, secret, nlen))
272*b077aed3SPierre Pronchery return 0;
273*b077aed3SPierre Pronchery
274*b077aed3SPierre Pronchery /* Step(3): out = RSAEP((n,e), z) */
275*b077aed3SPierre Pronchery ret = RSA_public_encrypt(nlen, secret, out, prsactx->rsa, RSA_NO_PADDING);
276*b077aed3SPierre Pronchery if (ret) {
277*b077aed3SPierre Pronchery ret = 1;
278*b077aed3SPierre Pronchery if (outlen != NULL)
279*b077aed3SPierre Pronchery *outlen = nlen;
280*b077aed3SPierre Pronchery if (secretlen != NULL)
281*b077aed3SPierre Pronchery *secretlen = nlen;
282*b077aed3SPierre Pronchery } else {
283*b077aed3SPierre Pronchery OPENSSL_cleanse(secret, nlen);
284*b077aed3SPierre Pronchery }
285*b077aed3SPierre Pronchery return ret;
286*b077aed3SPierre Pronchery }
287*b077aed3SPierre Pronchery
288*b077aed3SPierre Pronchery /*
289*b077aed3SPierre Pronchery * NIST.SP.800-56Br2
290*b077aed3SPierre Pronchery * 7.2.1.3 RSASVE Recovery Operation (RSASVE.RECOVER).
291*b077aed3SPierre Pronchery */
rsasve_recover(PROV_RSA_CTX * prsactx,unsigned char * out,size_t * outlen,const unsigned char * in,size_t inlen)292*b077aed3SPierre Pronchery static int rsasve_recover(PROV_RSA_CTX *prsactx,
293*b077aed3SPierre Pronchery unsigned char *out, size_t *outlen,
294*b077aed3SPierre Pronchery const unsigned char *in, size_t inlen)
295*b077aed3SPierre Pronchery {
296*b077aed3SPierre Pronchery size_t nlen;
297*b077aed3SPierre Pronchery
298*b077aed3SPierre Pronchery /* Step (1): get the byte length of n */
299*b077aed3SPierre Pronchery nlen = RSA_size(prsactx->rsa);
300*b077aed3SPierre Pronchery
301*b077aed3SPierre Pronchery if (out == NULL) {
302*b077aed3SPierre Pronchery if (nlen == 0) {
303*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
304*b077aed3SPierre Pronchery return 0;
305*b077aed3SPierre Pronchery }
306*b077aed3SPierre Pronchery *outlen = nlen;
307*b077aed3SPierre Pronchery return 1;
308*b077aed3SPierre Pronchery }
309*b077aed3SPierre Pronchery
310*b077aed3SPierre Pronchery /* Step (2): check the input ciphertext 'inlen' matches the nlen */
311*b077aed3SPierre Pronchery if (inlen != nlen) {
312*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_PROV, PROV_R_BAD_LENGTH);
313*b077aed3SPierre Pronchery return 0;
314*b077aed3SPierre Pronchery }
315*b077aed3SPierre Pronchery /* Step (3): out = RSADP((n,d), in) */
316*b077aed3SPierre Pronchery return (RSA_private_decrypt(inlen, in, out, prsactx->rsa, RSA_NO_PADDING) > 0);
317*b077aed3SPierre Pronchery }
318*b077aed3SPierre Pronchery
rsakem_generate(void * vprsactx,unsigned char * out,size_t * outlen,unsigned char * secret,size_t * secretlen)319*b077aed3SPierre Pronchery static int rsakem_generate(void *vprsactx, unsigned char *out, size_t *outlen,
320*b077aed3SPierre Pronchery unsigned char *secret, size_t *secretlen)
321*b077aed3SPierre Pronchery {
322*b077aed3SPierre Pronchery PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
323*b077aed3SPierre Pronchery
324*b077aed3SPierre Pronchery switch (prsactx->op) {
325*b077aed3SPierre Pronchery case KEM_OP_RSASVE:
326*b077aed3SPierre Pronchery return rsasve_generate(prsactx, out, outlen, secret, secretlen);
327*b077aed3SPierre Pronchery default:
328*b077aed3SPierre Pronchery return -2;
329*b077aed3SPierre Pronchery }
330*b077aed3SPierre Pronchery }
331*b077aed3SPierre Pronchery
rsakem_recover(void * vprsactx,unsigned char * out,size_t * outlen,const unsigned char * in,size_t inlen)332*b077aed3SPierre Pronchery static int rsakem_recover(void *vprsactx, unsigned char *out, size_t *outlen,
333*b077aed3SPierre Pronchery const unsigned char *in, size_t inlen)
334*b077aed3SPierre Pronchery {
335*b077aed3SPierre Pronchery PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
336*b077aed3SPierre Pronchery
337*b077aed3SPierre Pronchery switch (prsactx->op) {
338*b077aed3SPierre Pronchery case KEM_OP_RSASVE:
339*b077aed3SPierre Pronchery return rsasve_recover(prsactx, out, outlen, in, inlen);
340*b077aed3SPierre Pronchery default:
341*b077aed3SPierre Pronchery return -2;
342*b077aed3SPierre Pronchery }
343*b077aed3SPierre Pronchery }
344*b077aed3SPierre Pronchery
345*b077aed3SPierre Pronchery const OSSL_DISPATCH ossl_rsa_asym_kem_functions[] = {
346*b077aed3SPierre Pronchery { OSSL_FUNC_KEM_NEWCTX, (void (*)(void))rsakem_newctx },
347*b077aed3SPierre Pronchery { OSSL_FUNC_KEM_ENCAPSULATE_INIT,
348*b077aed3SPierre Pronchery (void (*)(void))rsakem_encapsulate_init },
349*b077aed3SPierre Pronchery { OSSL_FUNC_KEM_ENCAPSULATE, (void (*)(void))rsakem_generate },
350*b077aed3SPierre Pronchery { OSSL_FUNC_KEM_DECAPSULATE_INIT,
351*b077aed3SPierre Pronchery (void (*)(void))rsakem_decapsulate_init },
352*b077aed3SPierre Pronchery { OSSL_FUNC_KEM_DECAPSULATE, (void (*)(void))rsakem_recover },
353*b077aed3SPierre Pronchery { OSSL_FUNC_KEM_FREECTX, (void (*)(void))rsakem_freectx },
354*b077aed3SPierre Pronchery { OSSL_FUNC_KEM_DUPCTX, (void (*)(void))rsakem_dupctx },
355*b077aed3SPierre Pronchery { OSSL_FUNC_KEM_GET_CTX_PARAMS,
356*b077aed3SPierre Pronchery (void (*)(void))rsakem_get_ctx_params },
357*b077aed3SPierre Pronchery { OSSL_FUNC_KEM_GETTABLE_CTX_PARAMS,
358*b077aed3SPierre Pronchery (void (*)(void))rsakem_gettable_ctx_params },
359*b077aed3SPierre Pronchery { OSSL_FUNC_KEM_SET_CTX_PARAMS,
360*b077aed3SPierre Pronchery (void (*)(void))rsakem_set_ctx_params },
361*b077aed3SPierre Pronchery { OSSL_FUNC_KEM_SETTABLE_CTX_PARAMS,
362*b077aed3SPierre Pronchery (void (*)(void))rsakem_settable_ctx_params },
363*b077aed3SPierre Pronchery { 0, NULL }
364*b077aed3SPierre Pronchery };
365