xref: /freebsd-src/crypto/openssl/providers/implementations/kem/rsa_kem.c (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
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