88 */
99
1010#define pr_fmt (fmt ) "PKEY: "fmt
11- #include <linux/module.h>
12- #include <linux/export.h>
11+ #include <crypto/akcipher.h>
12+ #include <crypto/public_key.h>
13+ #include <crypto/sig.h>
14+ #include <keys/asymmetric-subtype.h>
15+ #include <linux/asn1.h>
16+ #include <linux/err.h>
1317#include <linux/kernel.h>
14- #include <linux/slab .h>
18+ #include <linux/module .h>
1519#include <linux/seq_file.h>
16- #include <linux/scatterlist.h>
17- #include <linux/asn1.h>
18- #include <keys/asymmetric-subtype.h>
19- #include <crypto/public_key.h>
20- #include <crypto/akcipher.h>
20+ #include <linux/slab.h>
21+ #include <linux/string.h>
2122
2223MODULE_DESCRIPTION ("In-software asymmetric public-key subtype" );
2324MODULE_AUTHOR ("Red Hat, Inc." );
@@ -65,10 +66,13 @@ static void public_key_destroy(void *payload0, void *payload3)
6566static int
6667software_key_determine_akcipher (const struct public_key * pkey ,
6768 const char * encoding , const char * hash_algo ,
68- char alg_name [CRYPTO_MAX_ALG_NAME ])
69+ char alg_name [CRYPTO_MAX_ALG_NAME ], bool * sig ,
70+ enum kernel_pkey_operation op )
6971{
7072 int n ;
7173
74+ * sig = true;
75+
7276 if (!encoding )
7377 return - EINVAL ;
7478
@@ -77,14 +81,18 @@ software_key_determine_akcipher(const struct public_key *pkey,
7781 * RSA signatures usually use EMSA-PKCS1-1_5 [RFC3447 sec 8.2].
7882 */
7983 if (strcmp (encoding , "pkcs1" ) == 0 ) {
80- if (!hash_algo )
84+ if (!hash_algo ) {
85+ * sig = false;
8186 n = snprintf (alg_name , CRYPTO_MAX_ALG_NAME ,
8287 "pkcs1pad(%s)" ,
8388 pkey -> pkey_algo );
84- else
89+ } else {
90+ * sig = op == kernel_pkey_sign ||
91+ op == kernel_pkey_verify ;
8592 n = snprintf (alg_name , CRYPTO_MAX_ALG_NAME ,
8693 "pkcs1pad(%s,%s)" ,
8794 pkey -> pkey_algo , hash_algo );
95+ }
8896 return n >= CRYPTO_MAX_ALG_NAME ? - EINVAL : 0 ;
8997 }
9098 if (strcmp (encoding , "raw" ) != 0 )
@@ -95,6 +103,7 @@ software_key_determine_akcipher(const struct public_key *pkey,
95103 */
96104 if (hash_algo )
97105 return - EINVAL ;
106+ * sig = false;
98107 } else if (strncmp (pkey -> pkey_algo , "ecdsa" , 5 ) == 0 ) {
99108 if (strcmp (encoding , "x962" ) != 0 )
100109 return - EINVAL ;
@@ -152,37 +161,70 @@ static int software_key_query(const struct kernel_pkey_params *params,
152161 struct crypto_akcipher * tfm ;
153162 struct public_key * pkey = params -> key -> payload .data [asym_crypto ];
154163 char alg_name [CRYPTO_MAX_ALG_NAME ];
164+ struct crypto_sig * sig ;
155165 u8 * key , * ptr ;
156166 int ret , len ;
167+ bool issig ;
157168
158169 ret = software_key_determine_akcipher (pkey , params -> encoding ,
159- params -> hash_algo , alg_name );
170+ params -> hash_algo , alg_name ,
171+ & issig , kernel_pkey_sign );
160172 if (ret < 0 )
161173 return ret ;
162174
163- tfm = crypto_alloc_akcipher (alg_name , 0 , 0 );
164- if (IS_ERR (tfm ))
165- return PTR_ERR (tfm );
166-
167- ret = - ENOMEM ;
168175 key = kmalloc (pkey -> keylen + sizeof (u32 ) * 2 + pkey -> paramlen ,
169176 GFP_KERNEL );
170177 if (!key )
171- goto error_free_tfm ;
178+ return - ENOMEM ;
179+
172180 memcpy (key , pkey -> key , pkey -> keylen );
173181 ptr = key + pkey -> keylen ;
174182 ptr = pkey_pack_u32 (ptr , pkey -> algo );
175183 ptr = pkey_pack_u32 (ptr , pkey -> paramlen );
176184 memcpy (ptr , pkey -> params , pkey -> paramlen );
177185
178- if (pkey -> key_is_private )
179- ret = crypto_akcipher_set_priv_key (tfm , key , pkey -> keylen );
180- else
181- ret = crypto_akcipher_set_pub_key (tfm , key , pkey -> keylen );
182- if (ret < 0 )
183- goto error_free_key ;
186+ if (issig ) {
187+ sig = crypto_alloc_sig (alg_name , 0 , 0 );
188+ if (IS_ERR (sig ))
189+ goto error_free_key ;
190+
191+ if (pkey -> key_is_private )
192+ ret = crypto_sig_set_privkey (sig , key , pkey -> keylen );
193+ else
194+ ret = crypto_sig_set_pubkey (sig , key , pkey -> keylen );
195+ if (ret < 0 )
196+ goto error_free_tfm ;
197+
198+ len = crypto_sig_maxsize (sig );
199+
200+ info -> supported_ops = KEYCTL_SUPPORTS_VERIFY ;
201+ if (pkey -> key_is_private )
202+ info -> supported_ops |= KEYCTL_SUPPORTS_SIGN ;
203+
204+ if (strcmp (params -> encoding , "pkcs1" ) == 0 ) {
205+ info -> supported_ops |= KEYCTL_SUPPORTS_ENCRYPT ;
206+ if (pkey -> key_is_private )
207+ info -> supported_ops |= KEYCTL_SUPPORTS_DECRYPT ;
208+ }
209+ } else {
210+ tfm = crypto_alloc_akcipher (alg_name , 0 , 0 );
211+ if (IS_ERR (tfm ))
212+ goto error_free_key ;
213+
214+ if (pkey -> key_is_private )
215+ ret = crypto_akcipher_set_priv_key (tfm , key , pkey -> keylen );
216+ else
217+ ret = crypto_akcipher_set_pub_key (tfm , key , pkey -> keylen );
218+ if (ret < 0 )
219+ goto error_free_tfm ;
220+
221+ len = crypto_akcipher_maxsize (tfm );
222+
223+ info -> supported_ops = KEYCTL_SUPPORTS_ENCRYPT ;
224+ if (pkey -> key_is_private )
225+ info -> supported_ops |= KEYCTL_SUPPORTS_DECRYPT ;
226+ }
184227
185- len = crypto_akcipher_maxsize (tfm );
186228 info -> key_size = len * 8 ;
187229
188230 if (strncmp (pkey -> pkey_algo , "ecdsa" , 5 ) == 0 ) {
@@ -208,17 +250,16 @@ static int software_key_query(const struct kernel_pkey_params *params,
208250
209251 info -> max_enc_size = len ;
210252 info -> max_dec_size = len ;
211- info -> supported_ops = (KEYCTL_SUPPORTS_ENCRYPT |
212- KEYCTL_SUPPORTS_VERIFY );
213- if (pkey -> key_is_private )
214- info -> supported_ops |= (KEYCTL_SUPPORTS_DECRYPT |
215- KEYCTL_SUPPORTS_SIGN );
253+
216254 ret = 0 ;
217255
256+ error_free_tfm :
257+ if (issig )
258+ crypto_free_sig (sig );
259+ else
260+ crypto_free_akcipher (tfm );
218261error_free_key :
219262 kfree (key );
220- error_free_tfm :
221- crypto_free_akcipher (tfm );
222263 pr_devel ("<==%s() = %d\n" , __func__ , ret );
223264 return ret ;
224265}
@@ -230,82 +271,97 @@ static int software_key_eds_op(struct kernel_pkey_params *params,
230271 const void * in , void * out )
231272{
232273 const struct public_key * pkey = params -> key -> payload .data [asym_crypto ];
233- struct akcipher_request * req ;
234- struct crypto_akcipher * tfm ;
235- struct crypto_wait cwait ;
236- struct scatterlist in_sg , out_sg ;
237274 char alg_name [CRYPTO_MAX_ALG_NAME ];
275+ struct crypto_akcipher * tfm ;
276+ struct crypto_sig * sig ;
238277 char * key , * ptr ;
278+ bool issig ;
279+ int ksz ;
239280 int ret ;
240281
241282 pr_devel ("==>%s()\n" , __func__ );
242283
243284 ret = software_key_determine_akcipher (pkey , params -> encoding ,
244- params -> hash_algo , alg_name );
285+ params -> hash_algo , alg_name ,
286+ & issig , params -> op );
245287 if (ret < 0 )
246288 return ret ;
247289
248- tfm = crypto_alloc_akcipher (alg_name , 0 , 0 );
249- if (IS_ERR (tfm ))
250- return PTR_ERR (tfm );
251-
252- ret = - ENOMEM ;
253- req = akcipher_request_alloc (tfm , GFP_KERNEL );
254- if (!req )
255- goto error_free_tfm ;
256-
257290 key = kmalloc (pkey -> keylen + sizeof (u32 ) * 2 + pkey -> paramlen ,
258291 GFP_KERNEL );
259292 if (!key )
260- goto error_free_req ;
293+ return - ENOMEM ;
261294
262295 memcpy (key , pkey -> key , pkey -> keylen );
263296 ptr = key + pkey -> keylen ;
264297 ptr = pkey_pack_u32 (ptr , pkey -> algo );
265298 ptr = pkey_pack_u32 (ptr , pkey -> paramlen );
266299 memcpy (ptr , pkey -> params , pkey -> paramlen );
267300
268- if (pkey -> key_is_private )
269- ret = crypto_akcipher_set_priv_key (tfm , key , pkey -> keylen );
270- else
271- ret = crypto_akcipher_set_pub_key (tfm , key , pkey -> keylen );
272- if (ret )
273- goto error_free_key ;
301+ if (issig ) {
302+ sig = crypto_alloc_sig (alg_name , 0 , 0 );
303+ if (IS_ERR (sig ))
304+ goto error_free_key ;
305+
306+ if (pkey -> key_is_private )
307+ ret = crypto_sig_set_privkey (sig , key , pkey -> keylen );
308+ else
309+ ret = crypto_sig_set_pubkey (sig , key , pkey -> keylen );
310+ if (ret )
311+ goto error_free_tfm ;
312+
313+ ksz = crypto_sig_maxsize (sig );
314+ } else {
315+ tfm = crypto_alloc_akcipher (alg_name , 0 , 0 );
316+ if (IS_ERR (tfm ))
317+ goto error_free_key ;
318+
319+ if (pkey -> key_is_private )
320+ ret = crypto_akcipher_set_priv_key (tfm , key , pkey -> keylen );
321+ else
322+ ret = crypto_akcipher_set_pub_key (tfm , key , pkey -> keylen );
323+ if (ret )
324+ goto error_free_tfm ;
325+
326+ ksz = crypto_akcipher_maxsize (tfm );
327+ }
274328
275- sg_init_one (& in_sg , in , params -> in_len );
276- sg_init_one (& out_sg , out , params -> out_len );
277- akcipher_request_set_crypt (req , & in_sg , & out_sg , params -> in_len ,
278- params -> out_len );
279- crypto_init_wait (& cwait );
280- akcipher_request_set_callback (req , CRYPTO_TFM_REQ_MAY_BACKLOG |
281- CRYPTO_TFM_REQ_MAY_SLEEP ,
282- crypto_req_done , & cwait );
329+ ret = - EINVAL ;
283330
284331 /* Perform the encryption calculation. */
285332 switch (params -> op ) {
286333 case kernel_pkey_encrypt :
287- ret = crypto_akcipher_encrypt (req );
334+ if (issig )
335+ break ;
336+ ret = crypto_akcipher_sync_encrypt (tfm , in , params -> in_len ,
337+ out , params -> out_len );
288338 break ;
289339 case kernel_pkey_decrypt :
290- ret = crypto_akcipher_decrypt (req );
340+ if (issig )
341+ break ;
342+ ret = crypto_akcipher_sync_decrypt (tfm , in , params -> in_len ,
343+ out , params -> out_len );
291344 break ;
292345 case kernel_pkey_sign :
293- ret = crypto_akcipher_sign (req );
346+ if (!issig )
347+ break ;
348+ ret = crypto_sig_sign (sig , in , params -> in_len ,
349+ out , params -> out_len );
294350 break ;
295351 default :
296352 BUG ();
297353 }
298354
299- ret = crypto_wait_req (ret , & cwait );
300355 if (ret == 0 )
301- ret = req -> dst_len ;
356+ ret = ksz ;
302357
358+ error_free_tfm :
359+ if (issig )
360+ crypto_free_sig (sig );
361+ else
362+ crypto_free_akcipher (tfm );
303363error_free_key :
304364 kfree (key );
305- error_free_req :
306- akcipher_request_free (req );
307- error_free_tfm :
308- crypto_free_akcipher (tfm );
309365 pr_devel ("<==%s() = %d\n" , __func__ , ret );
310366 return ret ;
311367}
@@ -316,12 +372,10 @@ static int software_key_eds_op(struct kernel_pkey_params *params,
316372int public_key_verify_signature (const struct public_key * pkey ,
317373 const struct public_key_signature * sig )
318374{
319- struct crypto_wait cwait ;
320- struct crypto_akcipher * tfm ;
321- struct akcipher_request * req ;
322- struct scatterlist src_sg [2 ];
323375 char alg_name [CRYPTO_MAX_ALG_NAME ];
376+ struct crypto_sig * tfm ;
324377 char * key , * ptr ;
378+ bool issig ;
325379 int ret ;
326380
327381 pr_devel ("==>%s()\n" , __func__ );
@@ -346,23 +400,19 @@ int public_key_verify_signature(const struct public_key *pkey,
346400 }
347401
348402 ret = software_key_determine_akcipher (pkey , sig -> encoding ,
349- sig -> hash_algo , alg_name );
403+ sig -> hash_algo , alg_name ,
404+ & issig , kernel_pkey_verify );
350405 if (ret < 0 )
351406 return ret ;
352407
353- tfm = crypto_alloc_akcipher (alg_name , 0 , 0 );
408+ tfm = crypto_alloc_sig (alg_name , 0 , 0 );
354409 if (IS_ERR (tfm ))
355410 return PTR_ERR (tfm );
356411
357- ret = - ENOMEM ;
358- req = akcipher_request_alloc (tfm , GFP_KERNEL );
359- if (!req )
360- goto error_free_tfm ;
361-
362412 key = kmalloc (pkey -> keylen + sizeof (u32 ) * 2 + pkey -> paramlen ,
363413 GFP_KERNEL );
364414 if (!key )
365- goto error_free_req ;
415+ goto error_free_tfm ;
366416
367417 memcpy (key , pkey -> key , pkey -> keylen );
368418 ptr = key + pkey -> keylen ;
@@ -371,29 +421,19 @@ int public_key_verify_signature(const struct public_key *pkey,
371421 memcpy (ptr , pkey -> params , pkey -> paramlen );
372422
373423 if (pkey -> key_is_private )
374- ret = crypto_akcipher_set_priv_key (tfm , key , pkey -> keylen );
424+ ret = crypto_sig_set_privkey (tfm , key , pkey -> keylen );
375425 else
376- ret = crypto_akcipher_set_pub_key (tfm , key , pkey -> keylen );
426+ ret = crypto_sig_set_pubkey (tfm , key , pkey -> keylen );
377427 if (ret )
378428 goto error_free_key ;
379429
380- sg_init_table (src_sg , 2 );
381- sg_set_buf (& src_sg [0 ], sig -> s , sig -> s_size );
382- sg_set_buf (& src_sg [1 ], sig -> digest , sig -> digest_size );
383- akcipher_request_set_crypt (req , src_sg , NULL , sig -> s_size ,
384- sig -> digest_size );
385- crypto_init_wait (& cwait );
386- akcipher_request_set_callback (req , CRYPTO_TFM_REQ_MAY_BACKLOG |
387- CRYPTO_TFM_REQ_MAY_SLEEP ,
388- crypto_req_done , & cwait );
389- ret = crypto_wait_req (crypto_akcipher_verify (req ), & cwait );
430+ ret = crypto_sig_verify (tfm , sig -> s , sig -> s_size ,
431+ sig -> digest , sig -> digest_size );
390432
391433error_free_key :
392434 kfree (key );
393- error_free_req :
394- akcipher_request_free (req );
395435error_free_tfm :
396- crypto_free_akcipher (tfm );
436+ crypto_free_sig (tfm );
397437 pr_devel ("<==%s() = %d\n" , __func__ , ret );
398438 if (WARN_ON_ONCE (ret > 0 ))
399439 ret = - EINVAL ;
0 commit comments