8
8
*/
9
9
10
10
#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>
13
17
#include <linux/kernel.h>
14
- #include <linux/slab .h>
18
+ #include <linux/module .h>
15
19
#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>
21
22
22
23
MODULE_DESCRIPTION ("In-software asymmetric public-key subtype" );
23
24
MODULE_AUTHOR ("Red Hat, Inc." );
@@ -65,10 +66,13 @@ static void public_key_destroy(void *payload0, void *payload3)
65
66
static int
66
67
software_key_determine_akcipher (const struct public_key * pkey ,
67
68
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 )
69
71
{
70
72
int n ;
71
73
74
+ * sig = true;
75
+
72
76
if (!encoding )
73
77
return - EINVAL ;
74
78
@@ -77,14 +81,18 @@ software_key_determine_akcipher(const struct public_key *pkey,
77
81
* RSA signatures usually use EMSA-PKCS1-1_5 [RFC3447 sec 8.2].
78
82
*/
79
83
if (strcmp (encoding , "pkcs1" ) == 0 ) {
80
- if (!hash_algo )
84
+ if (!hash_algo ) {
85
+ * sig = false;
81
86
n = snprintf (alg_name , CRYPTO_MAX_ALG_NAME ,
82
87
"pkcs1pad(%s)" ,
83
88
pkey -> pkey_algo );
84
- else
89
+ } else {
90
+ * sig = op == kernel_pkey_sign ||
91
+ op == kernel_pkey_verify ;
85
92
n = snprintf (alg_name , CRYPTO_MAX_ALG_NAME ,
86
93
"pkcs1pad(%s,%s)" ,
87
94
pkey -> pkey_algo , hash_algo );
95
+ }
88
96
return n >= CRYPTO_MAX_ALG_NAME ? - EINVAL : 0 ;
89
97
}
90
98
if (strcmp (encoding , "raw" ) != 0 )
@@ -95,6 +103,7 @@ software_key_determine_akcipher(const struct public_key *pkey,
95
103
*/
96
104
if (hash_algo )
97
105
return - EINVAL ;
106
+ * sig = false;
98
107
} else if (strncmp (pkey -> pkey_algo , "ecdsa" , 5 ) == 0 ) {
99
108
if (strcmp (encoding , "x962" ) != 0 )
100
109
return - EINVAL ;
@@ -152,37 +161,70 @@ static int software_key_query(const struct kernel_pkey_params *params,
152
161
struct crypto_akcipher * tfm ;
153
162
struct public_key * pkey = params -> key -> payload .data [asym_crypto ];
154
163
char alg_name [CRYPTO_MAX_ALG_NAME ];
164
+ struct crypto_sig * sig ;
155
165
u8 * key , * ptr ;
156
166
int ret , len ;
167
+ bool issig ;
157
168
158
169
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 );
160
172
if (ret < 0 )
161
173
return ret ;
162
174
163
- tfm = crypto_alloc_akcipher (alg_name , 0 , 0 );
164
- if (IS_ERR (tfm ))
165
- return PTR_ERR (tfm );
166
-
167
- ret = - ENOMEM ;
168
175
key = kmalloc (pkey -> keylen + sizeof (u32 ) * 2 + pkey -> paramlen ,
169
176
GFP_KERNEL );
170
177
if (!key )
171
- goto error_free_tfm ;
178
+ return - ENOMEM ;
179
+
172
180
memcpy (key , pkey -> key , pkey -> keylen );
173
181
ptr = key + pkey -> keylen ;
174
182
ptr = pkey_pack_u32 (ptr , pkey -> algo );
175
183
ptr = pkey_pack_u32 (ptr , pkey -> paramlen );
176
184
memcpy (ptr , pkey -> params , pkey -> paramlen );
177
185
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
+ }
184
227
185
- len = crypto_akcipher_maxsize (tfm );
186
228
info -> key_size = len * 8 ;
187
229
188
230
if (strncmp (pkey -> pkey_algo , "ecdsa" , 5 ) == 0 ) {
@@ -208,17 +250,16 @@ static int software_key_query(const struct kernel_pkey_params *params,
208
250
209
251
info -> max_enc_size = len ;
210
252
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
+
216
254
ret = 0 ;
217
255
256
+ error_free_tfm :
257
+ if (issig )
258
+ crypto_free_sig (sig );
259
+ else
260
+ crypto_free_akcipher (tfm );
218
261
error_free_key :
219
262
kfree (key );
220
- error_free_tfm :
221
- crypto_free_akcipher (tfm );
222
263
pr_devel ("<==%s() = %d\n" , __func__ , ret );
223
264
return ret ;
224
265
}
@@ -230,82 +271,97 @@ static int software_key_eds_op(struct kernel_pkey_params *params,
230
271
const void * in , void * out )
231
272
{
232
273
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 ;
237
274
char alg_name [CRYPTO_MAX_ALG_NAME ];
275
+ struct crypto_akcipher * tfm ;
276
+ struct crypto_sig * sig ;
238
277
char * key , * ptr ;
278
+ bool issig ;
279
+ int ksz ;
239
280
int ret ;
240
281
241
282
pr_devel ("==>%s()\n" , __func__ );
242
283
243
284
ret = software_key_determine_akcipher (pkey , params -> encoding ,
244
- params -> hash_algo , alg_name );
285
+ params -> hash_algo , alg_name ,
286
+ & issig , params -> op );
245
287
if (ret < 0 )
246
288
return ret ;
247
289
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
-
257
290
key = kmalloc (pkey -> keylen + sizeof (u32 ) * 2 + pkey -> paramlen ,
258
291
GFP_KERNEL );
259
292
if (!key )
260
- goto error_free_req ;
293
+ return - ENOMEM ;
261
294
262
295
memcpy (key , pkey -> key , pkey -> keylen );
263
296
ptr = key + pkey -> keylen ;
264
297
ptr = pkey_pack_u32 (ptr , pkey -> algo );
265
298
ptr = pkey_pack_u32 (ptr , pkey -> paramlen );
266
299
memcpy (ptr , pkey -> params , pkey -> paramlen );
267
300
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
+ }
274
328
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 ;
283
330
284
331
/* Perform the encryption calculation. */
285
332
switch (params -> op ) {
286
333
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 );
288
338
break ;
289
339
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 );
291
344
break ;
292
345
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 );
294
350
break ;
295
351
default :
296
352
BUG ();
297
353
}
298
354
299
- ret = crypto_wait_req (ret , & cwait );
300
355
if (ret == 0 )
301
- ret = req -> dst_len ;
356
+ ret = ksz ;
302
357
358
+ error_free_tfm :
359
+ if (issig )
360
+ crypto_free_sig (sig );
361
+ else
362
+ crypto_free_akcipher (tfm );
303
363
error_free_key :
304
364
kfree (key );
305
- error_free_req :
306
- akcipher_request_free (req );
307
- error_free_tfm :
308
- crypto_free_akcipher (tfm );
309
365
pr_devel ("<==%s() = %d\n" , __func__ , ret );
310
366
return ret ;
311
367
}
@@ -316,12 +372,10 @@ static int software_key_eds_op(struct kernel_pkey_params *params,
316
372
int public_key_verify_signature (const struct public_key * pkey ,
317
373
const struct public_key_signature * sig )
318
374
{
319
- struct crypto_wait cwait ;
320
- struct crypto_akcipher * tfm ;
321
- struct akcipher_request * req ;
322
- struct scatterlist src_sg [2 ];
323
375
char alg_name [CRYPTO_MAX_ALG_NAME ];
376
+ struct crypto_sig * tfm ;
324
377
char * key , * ptr ;
378
+ bool issig ;
325
379
int ret ;
326
380
327
381
pr_devel ("==>%s()\n" , __func__ );
@@ -346,23 +400,19 @@ int public_key_verify_signature(const struct public_key *pkey,
346
400
}
347
401
348
402
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 );
350
405
if (ret < 0 )
351
406
return ret ;
352
407
353
- tfm = crypto_alloc_akcipher (alg_name , 0 , 0 );
408
+ tfm = crypto_alloc_sig (alg_name , 0 , 0 );
354
409
if (IS_ERR (tfm ))
355
410
return PTR_ERR (tfm );
356
411
357
- ret = - ENOMEM ;
358
- req = akcipher_request_alloc (tfm , GFP_KERNEL );
359
- if (!req )
360
- goto error_free_tfm ;
361
-
362
412
key = kmalloc (pkey -> keylen + sizeof (u32 ) * 2 + pkey -> paramlen ,
363
413
GFP_KERNEL );
364
414
if (!key )
365
- goto error_free_req ;
415
+ goto error_free_tfm ;
366
416
367
417
memcpy (key , pkey -> key , pkey -> keylen );
368
418
ptr = key + pkey -> keylen ;
@@ -371,29 +421,19 @@ int public_key_verify_signature(const struct public_key *pkey,
371
421
memcpy (ptr , pkey -> params , pkey -> paramlen );
372
422
373
423
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 );
375
425
else
376
- ret = crypto_akcipher_set_pub_key (tfm , key , pkey -> keylen );
426
+ ret = crypto_sig_set_pubkey (tfm , key , pkey -> keylen );
377
427
if (ret )
378
428
goto error_free_key ;
379
429
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 );
390
432
391
433
error_free_key :
392
434
kfree (key );
393
- error_free_req :
394
- akcipher_request_free (req );
395
435
error_free_tfm :
396
- crypto_free_akcipher (tfm );
436
+ crypto_free_sig (tfm );
397
437
pr_devel ("<==%s() = %d\n" , __func__ , ret );
398
438
if (WARN_ON_ONCE (ret > 0 ))
399
439
ret = - EINVAL ;
0 commit comments