| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: cgd_crypto.c,v 1.21 2020/06/13 18:39:36 riastradh Exp $ */ | | 1 | /* $NetBSD: cgd_crypto.c,v 1.22 2020/06/13 18:40:14 riastradh Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2002 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2002 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Roland C. Dowdeswell. | | 8 | * by Roland C. Dowdeswell. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -27,27 +27,27 @@ | | | @@ -27,27 +27,27 @@ |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. | | 29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | /* | | 32 | /* |
33 | * Crypto Framework For cgd.c | | 33 | * Crypto Framework For cgd.c |
34 | * | | 34 | * |
35 | * This framework is temporary and awaits a more complete | | 35 | * This framework is temporary and awaits a more complete |
36 | * kernel wide crypto implementation. | | 36 | * kernel wide crypto implementation. |
37 | */ | | 37 | */ |
38 | | | 38 | |
39 | #include <sys/cdefs.h> | | 39 | #include <sys/cdefs.h> |
40 | __KERNEL_RCSID(0, "$NetBSD: cgd_crypto.c,v 1.21 2020/06/13 18:39:36 riastradh Exp $"); | | 40 | __KERNEL_RCSID(0, "$NetBSD: cgd_crypto.c,v 1.22 2020/06/13 18:40:14 riastradh Exp $"); |
41 | | | 41 | |
42 | #include <sys/param.h> | | 42 | #include <sys/param.h> |
43 | #include <sys/kmem.h> | | 43 | #include <sys/kmem.h> |
44 | #include <sys/systm.h> | | 44 | #include <sys/systm.h> |
45 | | | 45 | |
46 | #include <dev/cgd_crypto.h> | | 46 | #include <dev/cgd_crypto.h> |
47 | | | 47 | |
48 | #include <crypto/blowfish/blowfish.h> | | 48 | #include <crypto/blowfish/blowfish.h> |
49 | #include <crypto/des/des.h> | | 49 | #include <crypto/des/des.h> |
50 | #include <crypto/rijndael/rijndael-api-fst.h> | | 50 | #include <crypto/rijndael/rijndael-api-fst.h> |
51 | | | 51 | |
52 | /* | | 52 | /* |
53 | * The general framework provides only one generic function. | | 53 | * The general framework provides only one generic function. |
| @@ -260,112 +260,125 @@ cgd_cipher_aes_cbc(void *privdata, struc | | | @@ -260,112 +260,125 @@ cgd_cipher_aes_cbc(void *privdata, struc |
260 | case CGD_CIPHER_ENCRYPT: | | 260 | case CGD_CIPHER_ENCRYPT: |
261 | encd.ae_key = &apd->ap_enckey; | | 261 | encd.ae_key = &apd->ap_enckey; |
262 | cgd_cipher_uio(&encd, aes_cbc_enc_int, dstuio, srcuio); | | 262 | cgd_cipher_uio(&encd, aes_cbc_enc_int, dstuio, srcuio); |
263 | break; | | 263 | break; |
264 | case CGD_CIPHER_DECRYPT: | | 264 | case CGD_CIPHER_DECRYPT: |
265 | encd.ae_key = &apd->ap_deckey; | | 265 | encd.ae_key = &apd->ap_deckey; |
266 | cgd_cipher_uio(&encd, aes_cbc_dec_int, dstuio, srcuio); | | 266 | cgd_cipher_uio(&encd, aes_cbc_dec_int, dstuio, srcuio); |
267 | break; | | 267 | break; |
268 | default: | | 268 | default: |
269 | panic("%s: unrecognised direction %d", __func__, dir); | | 269 | panic("%s: unrecognised direction %d", __func__, dir); |
270 | } | | 270 | } |
271 | } | | 271 | } |
272 | | | 272 | |
| | | 273 | /* |
| | | 274 | * AES-XTS |
| | | 275 | */ |
| | | 276 | |
| | | 277 | struct aesxts { |
| | | 278 | keyInstance ax_enckey; |
| | | 279 | keyInstance ax_deckey; |
| | | 280 | keyInstance ax_tweakkey; |
| | | 281 | }; |
| | | 282 | |
| | | 283 | struct aesxts_state { |
| | | 284 | struct aesxts *axs_keys; |
| | | 285 | uint8_t axs_tweak[CGD_AES_BLOCK_SIZE]; |
| | | 286 | }; |
| | | 287 | |
273 | static void * | | 288 | static void * |
274 | cgd_cipher_aes_xts_init(size_t keylen, const void *xtskey, size_t *blocksize) | | 289 | cgd_cipher_aes_xts_init(size_t keylen, const void *xtskey, size_t *blocksize) |
275 | { | | 290 | { |
276 | struct aes_privdata *ap; | | 291 | struct aesxts *ax; |
277 | const char *key, *key2; /* XTS key is made of two AES keys. */ | | 292 | const char *key, *key2; /* XTS key is made of two AES keys. */ |
278 | | | 293 | |
279 | if (!blocksize) | | 294 | if (!blocksize) |
280 | return NULL; | | 295 | return NULL; |
281 | if (keylen != 256 && keylen != 512) | | 296 | if (keylen != 256 && keylen != 512) |
282 | return NULL; | | 297 | return NULL; |
283 | if (*blocksize == (size_t)-1) | | 298 | if (*blocksize == (size_t)-1) |
284 | *blocksize = 128; | | 299 | *blocksize = 128; |
285 | if (*blocksize != 128) | | 300 | if (*blocksize != 128) |
286 | return NULL; | | 301 | return NULL; |
287 | | | 302 | |
288 | ap = kmem_zalloc(2 * sizeof(*ap), KM_SLEEP); | | 303 | ax = kmem_zalloc(sizeof(*ax), KM_SLEEP); |
289 | keylen /= 2; | | 304 | keylen /= 2; |
290 | key = xtskey; | | 305 | key = xtskey; |
291 | key2 = key + keylen / CHAR_BIT; | | 306 | key2 = key + keylen / CHAR_BIT; |
292 | | | 307 | |
293 | rijndael_makeKey(&ap[0].ap_enckey, DIR_ENCRYPT, keylen, key); | | 308 | rijndael_makeKey(&ax->ax_enckey, DIR_ENCRYPT, keylen, key); |
294 | rijndael_makeKey(&ap[0].ap_deckey, DIR_DECRYPT, keylen, key); | | 309 | rijndael_makeKey(&ax->ax_deckey, DIR_DECRYPT, keylen, key); |
295 | rijndael_makeKey(&ap[1].ap_enckey, DIR_ENCRYPT, keylen, key2); | | 310 | rijndael_makeKey(&ax->ax_tweakkey, DIR_ENCRYPT, keylen, key2); |
296 | | | 311 | |
297 | return ap; | | 312 | return ax; |
298 | } | | 313 | } |
299 | | | 314 | |
300 | static void | | 315 | static void |
301 | cgd_cipher_aes_xts_destroy(void *data) | | 316 | cgd_cipher_aes_xts_destroy(void *cookie) |
302 | { | | 317 | { |
303 | struct aes_privdata *apd = data; | | 318 | struct aesxts *ax = cookie; |
304 | | | 319 | |
305 | explicit_memset(apd, 0, 2 * sizeof(*apd)); | | 320 | explicit_memset(ax, 0, sizeof(*ax)); |
306 | kmem_free(apd, 2 * sizeof(*apd)); | | 321 | kmem_free(ax, sizeof(*ax)); |
307 | } | | 322 | } |
308 | | | 323 | |
309 | static void | | 324 | static void |
310 | aes_xts_enc_int(void *privdata, void *dst, const void *src, size_t len) | | 325 | aes_xts_enc_int(void *state, void *dst, const void *src, size_t len) |
311 | { | | 326 | { |
312 | struct aes_encdata *ae = privdata; | | 327 | struct aesxts_state *axs = state; |
313 | cipherInstance cipher; | | 328 | cipherInstance cipher; |
314 | int cipher_ok __diagused; | | 329 | int cipher_ok __diagused; |
315 | | | 330 | |
316 | cipher_ok = rijndael_cipherInit(&cipher, MODE_XTS, ae->ae_iv); | | 331 | cipher_ok = rijndael_cipherInit(&cipher, MODE_XTS, axs->axs_tweak); |
317 | KASSERT(cipher_ok > 0); | | 332 | KASSERT(cipher_ok > 0); |
318 | rijndael_blockEncrypt(&cipher, ae->ae_key, src, /*inputbits*/len * 8, | | 333 | rijndael_blockEncrypt(&cipher, &axs->axs_keys->ax_enckey, src, |
319 | dst); | | 334 | /*inputbits*/len * 8, dst); |
320 | (void)memcpy(ae->ae_iv, cipher.IV, CGD_AES_BLOCK_SIZE); | | 335 | memcpy(axs->axs_tweak, cipher.IV, CGD_AES_BLOCK_SIZE); |
321 | } | | 336 | } |
322 | | | 337 | |
323 | static void | | 338 | static void |
324 | aes_xts_dec_int(void *privdata, void *dst, const void *src, size_t len) | | 339 | aes_xts_dec_int(void *state, void *dst, const void *src, size_t len) |
325 | { | | 340 | { |
326 | struct aes_encdata *ae = privdata; | | 341 | struct aesxts_state *axs = state; |
327 | cipherInstance cipher; | | 342 | cipherInstance cipher; |
328 | int cipher_ok __diagused; | | 343 | int cipher_ok __diagused; |
329 | | | 344 | |
330 | cipher_ok = rijndael_cipherInit(&cipher, MODE_XTS, ae->ae_iv); | | 345 | cipher_ok = rijndael_cipherInit(&cipher, MODE_XTS, axs->axs_tweak); |
331 | KASSERT(cipher_ok > 0); | | 346 | KASSERT(cipher_ok > 0); |
332 | rijndael_blockDecrypt(&cipher, ae->ae_key, src, /*inputbits*/len * 8, | | 347 | rijndael_blockDecrypt(&cipher, &axs->axs_keys->ax_deckey, src, |
333 | dst); | | 348 | /*inputbits*/len * 8, dst); |
334 | (void)memcpy(ae->ae_iv, cipher.IV, CGD_AES_BLOCK_SIZE); | | 349 | memcpy(axs->axs_tweak, cipher.IV, CGD_AES_BLOCK_SIZE); |
335 | } | | 350 | } |
336 | | | 351 | |
337 | static void | | 352 | static void |
338 | cgd_cipher_aes_xts(void *privdata, struct uio *dstuio, | | 353 | cgd_cipher_aes_xts(void *cookie, struct uio *dstuio, struct uio *srcuio, |
339 | struct uio *srcuio, const void *iv, int dir) | | 354 | const void *iv, int dir) |
340 | { | | 355 | { |
341 | struct aes_privdata *apd = privdata; | | 356 | struct aesxts *ax = cookie; |
342 | struct aes_encdata encd; | | 357 | struct aesxts_state axs = { .axs_keys = ax }; |
343 | cipherInstance cipher; | | 358 | cipherInstance cipher; |
344 | int cipher_ok __diagused; | | 359 | int cipher_ok __diagused; |
345 | | | 360 | |
346 | cipher_ok = rijndael_cipherInit(&cipher, MODE_ECB, NULL); | | 361 | cipher_ok = rijndael_cipherInit(&cipher, MODE_ECB, NULL); |
347 | KASSERT(cipher_ok > 0); | | 362 | KASSERT(cipher_ok > 0); |
348 | rijndael_blockEncrypt(&cipher, &apd[1].ap_enckey, iv, /*inputbits*/128, | | 363 | rijndael_blockEncrypt(&cipher, &ax->ax_tweakkey, iv, /*inputbits*/128, |
349 | encd.ae_iv); | | 364 | axs.axs_tweak); |
350 | | | 365 | |
351 | switch (dir) { | | 366 | switch (dir) { |
352 | case CGD_CIPHER_ENCRYPT: | | 367 | case CGD_CIPHER_ENCRYPT: |
353 | encd.ae_key = &apd->ap_enckey; | | 368 | cgd_cipher_uio(&axs, aes_xts_enc_int, dstuio, srcuio); |
354 | cgd_cipher_uio(&encd, aes_xts_enc_int, dstuio, srcuio); | | | |
355 | break; | | 369 | break; |
356 | case CGD_CIPHER_DECRYPT: | | 370 | case CGD_CIPHER_DECRYPT: |
357 | encd.ae_key = &apd->ap_deckey; | | 371 | cgd_cipher_uio(&axs, aes_xts_dec_int, dstuio, srcuio); |
358 | cgd_cipher_uio(&encd, aes_xts_dec_int, dstuio, srcuio); | | | |
359 | break; | | 372 | break; |
360 | default: | | 373 | default: |
361 | panic("%s: unrecognised direction %d", __func__, dir); | | 374 | panic("%s: unrecognised direction %d", __func__, dir); |
362 | } | | 375 | } |
363 | } | | 376 | } |
364 | | | 377 | |
365 | /* | | 378 | /* |
366 | * 3DES Framework | | 379 | * 3DES Framework |
367 | */ | | 380 | */ |
368 | | | 381 | |
369 | struct c3des_privdata { | | 382 | struct c3des_privdata { |
370 | des_key_schedule cp_key1; | | 383 | des_key_schedule cp_key1; |
371 | des_key_schedule cp_key2; | | 384 | des_key_schedule cp_key2; |