1
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
2
/* Large capacity key type
3
3
*
4
- * Copyright (C) 2017 Jason A. Donenfeld <[email protected] >. All Rights Reserved.
4
+ * Copyright (C) 2017-2020 Jason A. Donenfeld <[email protected] >. All Rights Reserved.
5
5
* Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
6
6
* Written by David Howells ([email protected] )
7
7
*/
12
12
#include <linux/file.h>
13
13
#include <linux/shmem_fs.h>
14
14
#include <linux/err.h>
15
- #include <linux/scatterlist.h>
16
15
#include <linux/random.h>
17
- #include <linux/vmalloc.h>
18
16
#include <keys/user-type.h>
19
17
#include <keys/big_key-type.h>
20
- #include <crypto/aead.h>
21
- #include <crypto/gcm.h>
22
-
23
- struct big_key_buf {
24
- unsigned int nr_pages ;
25
- void * virt ;
26
- struct scatterlist * sg ;
27
- struct page * pages [];
28
- };
18
+ #include <crypto/chacha20poly1305.h>
29
19
30
20
/*
31
21
* Layout of key payload words.
@@ -37,31 +27,13 @@ enum {
37
27
big_key_len ,
38
28
};
39
29
40
- /*
41
- * Crypto operation with big_key data
42
- */
43
- enum big_key_op {
44
- BIG_KEY_ENC ,
45
- BIG_KEY_DEC ,
46
- };
47
-
48
30
/*
49
31
* If the data is under this limit, there's no point creating a shm file to
50
32
* hold it as the permanently resident metadata for the shmem fs will be at
51
33
* least as large as the data.
52
34
*/
53
35
#define BIG_KEY_FILE_THRESHOLD (sizeof(struct inode) + sizeof(struct dentry))
54
36
55
- /*
56
- * Key size for big_key data encryption
57
- */
58
- #define ENC_KEY_SIZE 32
59
-
60
- /*
61
- * Authentication tag length
62
- */
63
- #define ENC_AUTHTAG_SIZE 16
64
-
65
37
/*
66
38
* big_key defined keys take an arbitrary string as the description and an
67
39
* arbitrary blob of data as the payload
@@ -75,136 +47,20 @@ struct key_type key_type_big_key = {
75
47
.destroy = big_key_destroy ,
76
48
.describe = big_key_describe ,
77
49
.read = big_key_read ,
78
- /* no ->update(); don't add it without changing big_key_crypt() nonce */
50
+ /* no ->update(); don't add it without changing chacha20poly1305's nonce */
79
51
};
80
52
81
- /*
82
- * Crypto names for big_key data authenticated encryption
83
- */
84
- static const char big_key_alg_name [] = "gcm(aes)" ;
85
- #define BIG_KEY_IV_SIZE GCM_AES_IV_SIZE
86
-
87
- /*
88
- * Crypto algorithms for big_key data authenticated encryption
89
- */
90
- static struct crypto_aead * big_key_aead ;
91
-
92
- /*
93
- * Since changing the key affects the entire object, we need a mutex.
94
- */
95
- static DEFINE_MUTEX (big_key_aead_lock );
96
-
97
- /*
98
- * Encrypt/decrypt big_key data
99
- */
100
- static int big_key_crypt (enum big_key_op op , struct big_key_buf * buf , size_t datalen , u8 * key )
101
- {
102
- int ret ;
103
- struct aead_request * aead_req ;
104
- /* We always use a zero nonce. The reason we can get away with this is
105
- * because we're using a different randomly generated key for every
106
- * different encryption. Notably, too, key_type_big_key doesn't define
107
- * an .update function, so there's no chance we'll wind up reusing the
108
- * key to encrypt updated data. Simply put: one key, one encryption.
109
- */
110
- u8 zero_nonce [BIG_KEY_IV_SIZE ];
111
-
112
- aead_req = aead_request_alloc (big_key_aead , GFP_KERNEL );
113
- if (!aead_req )
114
- return - ENOMEM ;
115
-
116
- memset (zero_nonce , 0 , sizeof (zero_nonce ));
117
- aead_request_set_crypt (aead_req , buf -> sg , buf -> sg , datalen , zero_nonce );
118
- aead_request_set_callback (aead_req , CRYPTO_TFM_REQ_MAY_SLEEP , NULL , NULL );
119
- aead_request_set_ad (aead_req , 0 );
120
-
121
- mutex_lock (& big_key_aead_lock );
122
- if (crypto_aead_setkey (big_key_aead , key , ENC_KEY_SIZE )) {
123
- ret = - EAGAIN ;
124
- goto error ;
125
- }
126
- if (op == BIG_KEY_ENC )
127
- ret = crypto_aead_encrypt (aead_req );
128
- else
129
- ret = crypto_aead_decrypt (aead_req );
130
- error :
131
- mutex_unlock (& big_key_aead_lock );
132
- aead_request_free (aead_req );
133
- return ret ;
134
- }
135
-
136
- /*
137
- * Free up the buffer.
138
- */
139
- static void big_key_free_buffer (struct big_key_buf * buf )
140
- {
141
- unsigned int i ;
142
-
143
- if (buf -> virt ) {
144
- memset (buf -> virt , 0 , buf -> nr_pages * PAGE_SIZE );
145
- vunmap (buf -> virt );
146
- }
147
-
148
- for (i = 0 ; i < buf -> nr_pages ; i ++ )
149
- if (buf -> pages [i ])
150
- __free_page (buf -> pages [i ]);
151
-
152
- kfree (buf );
153
- }
154
-
155
- /*
156
- * Allocate a buffer consisting of a set of pages with a virtual mapping
157
- * applied over them.
158
- */
159
- static void * big_key_alloc_buffer (size_t len )
160
- {
161
- struct big_key_buf * buf ;
162
- unsigned int npg = (len + PAGE_SIZE - 1 ) >> PAGE_SHIFT ;
163
- unsigned int i , l ;
164
-
165
- buf = kzalloc (sizeof (struct big_key_buf ) +
166
- sizeof (struct page ) * npg +
167
- sizeof (struct scatterlist ) * npg ,
168
- GFP_KERNEL );
169
- if (!buf )
170
- return NULL ;
171
-
172
- buf -> nr_pages = npg ;
173
- buf -> sg = (void * )(buf -> pages + npg );
174
- sg_init_table (buf -> sg , npg );
175
-
176
- for (i = 0 ; i < buf -> nr_pages ; i ++ ) {
177
- buf -> pages [i ] = alloc_page (GFP_KERNEL );
178
- if (!buf -> pages [i ])
179
- goto nomem ;
180
-
181
- l = min_t (size_t , len , PAGE_SIZE );
182
- sg_set_page (& buf -> sg [i ], buf -> pages [i ], l , 0 );
183
- len -= l ;
184
- }
185
-
186
- buf -> virt = vmap (buf -> pages , buf -> nr_pages , VM_MAP , PAGE_KERNEL );
187
- if (!buf -> virt )
188
- goto nomem ;
189
-
190
- return buf ;
191
-
192
- nomem :
193
- big_key_free_buffer (buf );
194
- return NULL ;
195
- }
196
-
197
53
/*
198
54
* Preparse a big key
199
55
*/
200
56
int big_key_preparse (struct key_preparsed_payload * prep )
201
57
{
202
- struct big_key_buf * buf ;
203
58
struct path * path = (struct path * )& prep -> payload .data [big_key_path ];
204
59
struct file * file ;
205
- u8 * enckey ;
60
+ u8 * buf , * enckey ;
206
61
ssize_t written ;
207
- size_t datalen = prep -> datalen , enclen = datalen + ENC_AUTHTAG_SIZE ;
62
+ size_t datalen = prep -> datalen ;
63
+ size_t enclen = datalen + CHACHA20POLY1305_AUTHTAG_SIZE ;
208
64
int ret ;
209
65
210
66
if (datalen <= 0 || datalen > 1024 * 1024 || !prep -> data )
@@ -220,28 +76,28 @@ int big_key_preparse(struct key_preparsed_payload *prep)
220
76
* to be swapped out if needed.
221
77
*
222
78
* File content is stored encrypted with randomly generated key.
79
+ * Since the key is random for each file, we can set the nonce
80
+ * to zero, provided we never define a ->update() call.
223
81
*/
224
82
loff_t pos = 0 ;
225
83
226
- buf = big_key_alloc_buffer (enclen );
84
+ buf = kvmalloc (enclen , GFP_KERNEL );
227
85
if (!buf )
228
86
return - ENOMEM ;
229
- memcpy (buf -> virt , prep -> data , datalen );
230
87
231
88
/* generate random key */
232
- enckey = kmalloc (ENC_KEY_SIZE , GFP_KERNEL );
89
+ enckey = kmalloc (CHACHA20POLY1305_KEY_SIZE , GFP_KERNEL );
233
90
if (!enckey ) {
234
91
ret = - ENOMEM ;
235
92
goto error ;
236
93
}
237
- ret = get_random_bytes_wait (enckey , ENC_KEY_SIZE );
94
+ ret = get_random_bytes_wait (enckey , CHACHA20POLY1305_KEY_SIZE );
238
95
if (unlikely (ret ))
239
96
goto err_enckey ;
240
97
241
- /* encrypt aligned data */
242
- ret = big_key_crypt (BIG_KEY_ENC , buf , datalen , enckey );
243
- if (ret )
244
- goto err_enckey ;
98
+ /* encrypt data */
99
+ chacha20poly1305_encrypt (buf , prep -> data , datalen , NULL , 0 ,
100
+ 0 , enckey );
245
101
246
102
/* save aligned data to file */
247
103
file = shmem_kernel_file_setup ("" , enclen , 0 );
@@ -250,11 +106,11 @@ int big_key_preparse(struct key_preparsed_payload *prep)
250
106
goto err_enckey ;
251
107
}
252
108
253
- written = kernel_write (file , buf -> virt , enclen , & pos );
109
+ written = kernel_write (file , buf , enclen , & pos );
254
110
if (written != enclen ) {
255
111
ret = written ;
256
112
if (written >= 0 )
257
- ret = - ENOMEM ;
113
+ ret = - EIO ;
258
114
goto err_fput ;
259
115
}
260
116
@@ -265,7 +121,8 @@ int big_key_preparse(struct key_preparsed_payload *prep)
265
121
* path = file -> f_path ;
266
122
path_get (path );
267
123
fput (file );
268
- big_key_free_buffer (buf );
124
+ memzero_explicit (buf , enclen );
125
+ kvfree (buf );
269
126
} else {
270
127
/* Just store the data in a buffer */
271
128
void * data = kmalloc (datalen , GFP_KERNEL );
@@ -283,7 +140,8 @@ int big_key_preparse(struct key_preparsed_payload *prep)
283
140
err_enckey :
284
141
kzfree (enckey );
285
142
error :
286
- big_key_free_buffer (buf );
143
+ memzero_explicit (buf , enclen );
144
+ kvfree (buf );
287
145
return ret ;
288
146
}
289
147
@@ -361,14 +219,13 @@ long big_key_read(const struct key *key, char *buffer, size_t buflen)
361
219
return datalen ;
362
220
363
221
if (datalen > BIG_KEY_FILE_THRESHOLD ) {
364
- struct big_key_buf * buf ;
365
222
struct path * path = (struct path * )& key -> payload .data [big_key_path ];
366
223
struct file * file ;
367
- u8 * enckey = (u8 * )key -> payload .data [big_key_data ];
368
- size_t enclen = datalen + ENC_AUTHTAG_SIZE ;
224
+ u8 * buf , * enckey = (u8 * )key -> payload .data [big_key_data ];
225
+ size_t enclen = datalen + CHACHA20POLY1305_AUTHTAG_SIZE ;
369
226
loff_t pos = 0 ;
370
227
371
- buf = big_key_alloc_buffer (enclen );
228
+ buf = kvmalloc (enclen , GFP_KERNEL );
372
229
if (!buf )
373
230
return - ENOMEM ;
374
231
@@ -379,25 +236,28 @@ long big_key_read(const struct key *key, char *buffer, size_t buflen)
379
236
}
380
237
381
238
/* read file to kernel and decrypt */
382
- ret = kernel_read (file , buf -> virt , enclen , & pos );
383
- if (ret >= 0 && ret != enclen ) {
384
- ret = - EIO ;
239
+ ret = kernel_read (file , buf , enclen , & pos );
240
+ if (ret != enclen ) {
241
+ if (ret >= 0 )
242
+ ret = - EIO ;
385
243
goto err_fput ;
386
244
}
387
245
388
- ret = big_key_crypt (BIG_KEY_DEC , buf , enclen , enckey );
389
- if (ret )
246
+ ret = chacha20poly1305_decrypt (buf , buf , enclen , NULL , 0 , 0 ,
247
+ enckey ) ? 0 : - EBADMSG ;
248
+ if (unlikely (ret ))
390
249
goto err_fput ;
391
250
392
251
ret = datalen ;
393
252
394
253
/* copy out decrypted data */
395
- memcpy (buffer , buf -> virt , datalen );
254
+ memcpy (buffer , buf , datalen );
396
255
397
256
err_fput :
398
257
fput (file );
399
258
error :
400
- big_key_free_buffer (buf );
259
+ memzero_explicit (buf , enclen );
260
+ kvfree (buf );
401
261
} else {
402
262
ret = datalen ;
403
263
memcpy (buffer , key -> payload .data [big_key_data ], datalen );
@@ -411,39 +271,7 @@ long big_key_read(const struct key *key, char *buffer, size_t buflen)
411
271
*/
412
272
static int __init big_key_init (void )
413
273
{
414
- int ret ;
415
-
416
- /* init block cipher */
417
- big_key_aead = crypto_alloc_aead (big_key_alg_name , 0 , CRYPTO_ALG_ASYNC );
418
- if (IS_ERR (big_key_aead )) {
419
- ret = PTR_ERR (big_key_aead );
420
- pr_err ("Can't alloc crypto: %d\n" , ret );
421
- return ret ;
422
- }
423
-
424
- if (unlikely (crypto_aead_ivsize (big_key_aead ) != BIG_KEY_IV_SIZE )) {
425
- WARN (1 , "big key algorithm changed?" );
426
- ret = - EINVAL ;
427
- goto free_aead ;
428
- }
429
-
430
- ret = crypto_aead_setauthsize (big_key_aead , ENC_AUTHTAG_SIZE );
431
- if (ret < 0 ) {
432
- pr_err ("Can't set crypto auth tag len: %d\n" , ret );
433
- goto free_aead ;
434
- }
435
-
436
- ret = register_key_type (& key_type_big_key );
437
- if (ret < 0 ) {
438
- pr_err ("Can't register type: %d\n" , ret );
439
- goto free_aead ;
440
- }
441
-
442
- return 0 ;
443
-
444
- free_aead :
445
- crypto_free_aead (big_key_aead );
446
- return ret ;
274
+ return register_key_type (& key_type_big_key );
447
275
}
448
276
449
277
late_initcall (big_key_init );
0 commit comments