17
17
#include <linux/set_memory.h>
18
18
#include <linux/fs.h>
19
19
#include <linux/tsm.h>
20
- #include <crypto/aead.h>
21
- #include <linux/scatterlist.h>
20
+ #include <crypto/gcm.h>
22
21
#include <linux/psp-sev.h>
23
22
#include <linux/sockptr.h>
24
23
#include <linux/cleanup.h>
31
30
#include <asm/sev.h>
32
31
33
32
#define DEVICE_NAME "sev-guest"
34
- #define AAD_LEN 48
35
- #define MSG_HDR_VER 1
36
33
37
34
#define SNP_REQ_MAX_RETRY_DURATION (60*HZ)
38
35
#define SNP_REQ_RETRY_DELAY (2*HZ)
39
36
40
37
#define SVSM_MAX_RETRIES 3
41
38
42
- struct snp_guest_crypto {
43
- struct crypto_aead * tfm ;
44
- u8 * iv , * authtag ;
45
- int iv_len , a_len ;
46
- };
47
-
48
39
struct snp_guest_dev {
49
40
struct device * dev ;
50
41
struct miscdevice misc ;
51
42
52
43
void * certs_data ;
53
- struct snp_guest_crypto * crypto ;
44
+ struct aesgcm_ctx * ctx ;
54
45
/* request and response are in unencrypted memory */
55
46
struct snp_guest_msg * request , * response ;
56
47
@@ -169,132 +160,31 @@ static inline struct snp_guest_dev *to_snp_dev(struct file *file)
169
160
return container_of (dev , struct snp_guest_dev , misc );
170
161
}
171
162
172
- static struct snp_guest_crypto * init_crypto ( struct snp_guest_dev * snp_dev , u8 * key , size_t keylen )
163
+ static struct aesgcm_ctx * snp_init_crypto ( u8 * key , size_t keylen )
173
164
{
174
- struct snp_guest_crypto * crypto ;
165
+ struct aesgcm_ctx * ctx ;
175
166
176
- crypto = kzalloc (sizeof (* crypto ), GFP_KERNEL_ACCOUNT );
177
- if (!crypto )
167
+ ctx = kzalloc (sizeof (* ctx ), GFP_KERNEL_ACCOUNT );
168
+ if (!ctx )
178
169
return NULL ;
179
170
180
- crypto -> tfm = crypto_alloc_aead ("gcm(aes)" , 0 , 0 );
181
- if (IS_ERR (crypto -> tfm ))
182
- goto e_free ;
183
-
184
- if (crypto_aead_setkey (crypto -> tfm , key , keylen ))
185
- goto e_free_crypto ;
186
-
187
- crypto -> iv_len = crypto_aead_ivsize (crypto -> tfm );
188
- crypto -> iv = kmalloc (crypto -> iv_len , GFP_KERNEL_ACCOUNT );
189
- if (!crypto -> iv )
190
- goto e_free_crypto ;
191
-
192
- if (crypto_aead_authsize (crypto -> tfm ) > MAX_AUTHTAG_LEN ) {
193
- if (crypto_aead_setauthsize (crypto -> tfm , MAX_AUTHTAG_LEN )) {
194
- dev_err (snp_dev -> dev , "failed to set authsize to %d\n" , MAX_AUTHTAG_LEN );
195
- goto e_free_iv ;
196
- }
171
+ if (aesgcm_expandkey (ctx , key , keylen , AUTHTAG_LEN )) {
172
+ pr_err ("Crypto context initialization failed\n" );
173
+ kfree (ctx );
174
+ return NULL ;
197
175
}
198
176
199
- crypto -> a_len = crypto_aead_authsize (crypto -> tfm );
200
- crypto -> authtag = kmalloc (crypto -> a_len , GFP_KERNEL_ACCOUNT );
201
- if (!crypto -> authtag )
202
- goto e_free_iv ;
203
-
204
- return crypto ;
205
-
206
- e_free_iv :
207
- kfree (crypto -> iv );
208
- e_free_crypto :
209
- crypto_free_aead (crypto -> tfm );
210
- e_free :
211
- kfree (crypto );
212
-
213
- return NULL ;
214
- }
215
-
216
- static void deinit_crypto (struct snp_guest_crypto * crypto )
217
- {
218
- crypto_free_aead (crypto -> tfm );
219
- kfree (crypto -> iv );
220
- kfree (crypto -> authtag );
221
- kfree (crypto );
222
- }
223
-
224
- static int enc_dec_message (struct snp_guest_crypto * crypto , struct snp_guest_msg * msg ,
225
- u8 * src_buf , u8 * dst_buf , size_t len , bool enc )
226
- {
227
- struct snp_guest_msg_hdr * hdr = & msg -> hdr ;
228
- struct scatterlist src [3 ], dst [3 ];
229
- DECLARE_CRYPTO_WAIT (wait );
230
- struct aead_request * req ;
231
- int ret ;
232
-
233
- req = aead_request_alloc (crypto -> tfm , GFP_KERNEL );
234
- if (!req )
235
- return - ENOMEM ;
236
-
237
- /*
238
- * AEAD memory operations:
239
- * +------ AAD -------+------- DATA -----+---- AUTHTAG----+
240
- * | msg header | plaintext | hdr->authtag |
241
- * | bytes 30h - 5Fh | or | |
242
- * | | cipher | |
243
- * +------------------+------------------+----------------+
244
- */
245
- sg_init_table (src , 3 );
246
- sg_set_buf (& src [0 ], & hdr -> algo , AAD_LEN );
247
- sg_set_buf (& src [1 ], src_buf , hdr -> msg_sz );
248
- sg_set_buf (& src [2 ], hdr -> authtag , crypto -> a_len );
249
-
250
- sg_init_table (dst , 3 );
251
- sg_set_buf (& dst [0 ], & hdr -> algo , AAD_LEN );
252
- sg_set_buf (& dst [1 ], dst_buf , hdr -> msg_sz );
253
- sg_set_buf (& dst [2 ], hdr -> authtag , crypto -> a_len );
254
-
255
- aead_request_set_ad (req , AAD_LEN );
256
- aead_request_set_tfm (req , crypto -> tfm );
257
- aead_request_set_callback (req , 0 , crypto_req_done , & wait );
258
-
259
- aead_request_set_crypt (req , src , dst , len , crypto -> iv );
260
- ret = crypto_wait_req (enc ? crypto_aead_encrypt (req ) : crypto_aead_decrypt (req ), & wait );
261
-
262
- aead_request_free (req );
263
- return ret ;
264
- }
265
-
266
- static int __enc_payload (struct snp_guest_dev * snp_dev , struct snp_guest_msg * msg ,
267
- void * plaintext , size_t len )
268
- {
269
- struct snp_guest_crypto * crypto = snp_dev -> crypto ;
270
- struct snp_guest_msg_hdr * hdr = & msg -> hdr ;
271
-
272
- memset (crypto -> iv , 0 , crypto -> iv_len );
273
- memcpy (crypto -> iv , & hdr -> msg_seqno , sizeof (hdr -> msg_seqno ));
274
-
275
- return enc_dec_message (crypto , msg , plaintext , msg -> payload , len , true);
276
- }
277
-
278
- static int dec_payload (struct snp_guest_dev * snp_dev , struct snp_guest_msg * msg ,
279
- void * plaintext , size_t len )
280
- {
281
- struct snp_guest_crypto * crypto = snp_dev -> crypto ;
282
- struct snp_guest_msg_hdr * hdr = & msg -> hdr ;
283
-
284
- /* Build IV with response buffer sequence number */
285
- memset (crypto -> iv , 0 , crypto -> iv_len );
286
- memcpy (crypto -> iv , & hdr -> msg_seqno , sizeof (hdr -> msg_seqno ));
287
-
288
- return enc_dec_message (crypto , msg , msg -> payload , plaintext , len , false);
177
+ return ctx ;
289
178
}
290
179
291
180
static int verify_and_dec_payload (struct snp_guest_dev * snp_dev , void * payload , u32 sz )
292
181
{
293
- struct snp_guest_crypto * crypto = snp_dev -> crypto ;
294
182
struct snp_guest_msg * resp_msg = & snp_dev -> secret_response ;
295
183
struct snp_guest_msg * req_msg = & snp_dev -> secret_request ;
296
184
struct snp_guest_msg_hdr * req_msg_hdr = & req_msg -> hdr ;
297
185
struct snp_guest_msg_hdr * resp_msg_hdr = & resp_msg -> hdr ;
186
+ struct aesgcm_ctx * ctx = snp_dev -> ctx ;
187
+ u8 iv [GCM_AES_IV_SIZE ] = {};
298
188
299
189
pr_debug ("response [seqno %lld type %d version %d sz %d]\n" ,
300
190
resp_msg_hdr -> msg_seqno , resp_msg_hdr -> msg_type , resp_msg_hdr -> msg_version ,
@@ -316,18 +206,25 @@ static int verify_and_dec_payload(struct snp_guest_dev *snp_dev, void *payload,
316
206
* If the message size is greater than our buffer length then return
317
207
* an error.
318
208
*/
319
- if (unlikely ((resp_msg_hdr -> msg_sz + crypto -> a_len ) > sz ))
209
+ if (unlikely ((resp_msg_hdr -> msg_sz + ctx -> authsize ) > sz ))
320
210
return - EBADMSG ;
321
211
322
212
/* Decrypt the payload */
323
- return dec_payload (snp_dev , resp_msg , payload , resp_msg_hdr -> msg_sz + crypto -> a_len );
213
+ memcpy (iv , & resp_msg_hdr -> msg_seqno , min (sizeof (iv ), sizeof (resp_msg_hdr -> msg_seqno )));
214
+ if (!aesgcm_decrypt (ctx , payload , resp_msg -> payload , resp_msg_hdr -> msg_sz ,
215
+ & resp_msg_hdr -> algo , AAD_LEN , iv , resp_msg_hdr -> authtag ))
216
+ return - EBADMSG ;
217
+
218
+ return 0 ;
324
219
}
325
220
326
221
static int enc_payload (struct snp_guest_dev * snp_dev , u64 seqno , int version , u8 type ,
327
222
void * payload , size_t sz )
328
223
{
329
224
struct snp_guest_msg * msg = & snp_dev -> secret_request ;
330
225
struct snp_guest_msg_hdr * hdr = & msg -> hdr ;
226
+ struct aesgcm_ctx * ctx = snp_dev -> ctx ;
227
+ u8 iv [GCM_AES_IV_SIZE ] = {};
331
228
332
229
memset (msg , 0 , sizeof (* msg ));
333
230
@@ -347,7 +244,14 @@ static int enc_payload(struct snp_guest_dev *snp_dev, u64 seqno, int version, u8
347
244
pr_debug ("request [seqno %lld type %d version %d sz %d]\n" ,
348
245
hdr -> msg_seqno , hdr -> msg_type , hdr -> msg_version , hdr -> msg_sz );
349
246
350
- return __enc_payload (snp_dev , msg , payload , sz );
247
+ if (WARN_ON ((sz + ctx -> authsize ) > sizeof (msg -> payload )))
248
+ return - EBADMSG ;
249
+
250
+ memcpy (iv , & hdr -> msg_seqno , min (sizeof (iv ), sizeof (hdr -> msg_seqno )));
251
+ aesgcm_encrypt (ctx , msg -> payload , payload , sz , & hdr -> algo , AAD_LEN ,
252
+ iv , hdr -> authtag );
253
+
254
+ return 0 ;
351
255
}
352
256
353
257
static int __handle_guest_request (struct snp_guest_dev * snp_dev , u64 exit_code ,
@@ -495,7 +399,6 @@ struct snp_req_resp {
495
399
496
400
static int get_report (struct snp_guest_dev * snp_dev , struct snp_guest_request_ioctl * arg )
497
401
{
498
- struct snp_guest_crypto * crypto = snp_dev -> crypto ;
499
402
struct snp_report_req * report_req = & snp_dev -> req .report ;
500
403
struct snp_report_resp * report_resp ;
501
404
int rc , resp_len ;
@@ -513,7 +416,7 @@ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_io
513
416
* response payload. Make sure that it has enough space to cover the
514
417
* authtag.
515
418
*/
516
- resp_len = sizeof (report_resp -> data ) + crypto -> a_len ;
419
+ resp_len = sizeof (report_resp -> data ) + snp_dev -> ctx -> authsize ;
517
420
report_resp = kzalloc (resp_len , GFP_KERNEL_ACCOUNT );
518
421
if (!report_resp )
519
422
return - ENOMEM ;
@@ -534,7 +437,6 @@ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_io
534
437
static int get_derived_key (struct snp_guest_dev * snp_dev , struct snp_guest_request_ioctl * arg )
535
438
{
536
439
struct snp_derived_key_req * derived_key_req = & snp_dev -> req .derived_key ;
537
- struct snp_guest_crypto * crypto = snp_dev -> crypto ;
538
440
struct snp_derived_key_resp derived_key_resp = {0 };
539
441
int rc , resp_len ;
540
442
/* Response data is 64 bytes and max authsize for GCM is 16 bytes. */
@@ -550,7 +452,7 @@ static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_reque
550
452
* response payload. Make sure that it has enough space to cover the
551
453
* authtag.
552
454
*/
553
- resp_len = sizeof (derived_key_resp .data ) + crypto -> a_len ;
455
+ resp_len = sizeof (derived_key_resp .data ) + snp_dev -> ctx -> authsize ;
554
456
if (sizeof (buf ) < resp_len )
555
457
return - ENOMEM ;
556
458
@@ -579,7 +481,6 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques
579
481
580
482
{
581
483
struct snp_ext_report_req * report_req = & snp_dev -> req .ext_report ;
582
- struct snp_guest_crypto * crypto = snp_dev -> crypto ;
583
484
struct snp_report_resp * report_resp ;
584
485
int ret , npages = 0 , resp_len ;
585
486
sockptr_t certs_address ;
@@ -622,7 +523,7 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques
622
523
* response payload. Make sure that it has enough space to cover the
623
524
* authtag.
624
525
*/
625
- resp_len = sizeof (report_resp -> data ) + crypto -> a_len ;
526
+ resp_len = sizeof (report_resp -> data ) + snp_dev -> ctx -> authsize ;
626
527
report_resp = kzalloc (resp_len , GFP_KERNEL_ACCOUNT );
627
528
if (!report_resp )
628
529
return - ENOMEM ;
@@ -1147,8 +1048,8 @@ static int __init sev_guest_probe(struct platform_device *pdev)
1147
1048
goto e_free_response ;
1148
1049
1149
1050
ret = - EIO ;
1150
- snp_dev -> crypto = init_crypto ( snp_dev , snp_dev -> vmpck , VMPCK_KEY_LEN );
1151
- if (!snp_dev -> crypto )
1051
+ snp_dev -> ctx = snp_init_crypto ( snp_dev -> vmpck , VMPCK_KEY_LEN );
1052
+ if (!snp_dev -> ctx )
1152
1053
goto e_free_cert_data ;
1153
1054
1154
1055
misc = & snp_dev -> misc ;
@@ -1174,11 +1075,13 @@ static int __init sev_guest_probe(struct platform_device *pdev)
1174
1075
1175
1076
ret = misc_register (misc );
1176
1077
if (ret )
1177
- goto e_free_cert_data ;
1078
+ goto e_free_ctx ;
1178
1079
1179
1080
dev_info (dev , "Initialized SEV guest driver (using VMPCK%d communication key)\n" , vmpck_id );
1180
1081
return 0 ;
1181
1082
1083
+ e_free_ctx :
1084
+ kfree (snp_dev -> ctx );
1182
1085
e_free_cert_data :
1183
1086
free_shared_pages (snp_dev -> certs_data , SEV_FW_BLOB_MAX_SIZE );
1184
1087
e_free_response :
@@ -1197,7 +1100,7 @@ static void __exit sev_guest_remove(struct platform_device *pdev)
1197
1100
free_shared_pages (snp_dev -> certs_data , SEV_FW_BLOB_MAX_SIZE );
1198
1101
free_shared_pages (snp_dev -> response , sizeof (struct snp_guest_msg ));
1199
1102
free_shared_pages (snp_dev -> request , sizeof (struct snp_guest_msg ));
1200
- deinit_crypto (snp_dev -> crypto );
1103
+ kfree (snp_dev -> ctx );
1201
1104
misc_deregister (& snp_dev -> misc );
1202
1105
}
1203
1106
0 commit comments