1 /* $NetBSD: cgd_crypto.c,v 1.14 2016/12/11 00:20:49 alnsn Exp $ */ 2 3 /*- 4 * Copyright (c) 2002 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Roland C. Dowdeswell. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 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 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Crypto Framework For cgd.c 34 * 35 * This framework is temporary and awaits a more complete 36 * kernel wide crypto implementation. 37 */ 38 39 #include <sys/cdefs.h> 40 __KERNEL_RCSID(0, "$NetBSD: cgd_crypto.c,v 1.14 2016/12/11 00:20:49 alnsn Exp $"); 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/malloc.h> 45 46 #include <dev/cgd_crypto.h> 47 48 #include <crypto/rijndael/rijndael-api-fst.h> 49 #include <crypto/des/des.h> 50 #include <crypto/blowfish/blowfish.h> 51 52 #ifdef DIAGNOSTIC 53 #define DIAGPANIC(x) panic x 54 #else 55 #define DIAGPANIC(x) 56 #endif 57 58 /* 59 * The general framework provides only one generic function. 60 * It takes the name of an algorith and returns a struct cryptfuncs * 61 * for it. It is up to the initialisation routines of the algorithm 62 * to check key size and block size. 63 */ 64 65 static cfunc_init cgd_cipher_aes_cbc_init; 66 static cfunc_destroy cgd_cipher_aes_cbc_destroy; 67 static cfunc_cipher cgd_cipher_aes_cbc; 68 static cfunc_cipher_prep cgd_cipher_aes_cbc_prep; 69 70 static cfunc_init cgd_cipher_aes_xts_init; 71 static cfunc_destroy cgd_cipher_aes_xts_destroy; 72 static cfunc_cipher cgd_cipher_aes_xts; 73 static cfunc_cipher_prep cgd_cipher_aes_xts_prep; 74 75 static cfunc_init cgd_cipher_3des_init; 76 static cfunc_destroy cgd_cipher_3des_destroy; 77 static cfunc_cipher cgd_cipher_3des_cbc; 78 static cfunc_cipher_prep cgd_cipher_3des_cbc_prep; 79 80 static cfunc_init cgd_cipher_bf_init; 81 static cfunc_destroy cgd_cipher_bf_destroy; 82 static cfunc_cipher cgd_cipher_bf_cbc; 83 static cfunc_cipher_prep cgd_cipher_bf_cbc_prep; 84 85 static const struct cryptfuncs cf[] = { 86 { 87 .cf_name = "aes-xts", 88 .cf_init = cgd_cipher_aes_xts_init, 89 .cf_destroy = cgd_cipher_aes_xts_destroy, 90 .cf_cipher = cgd_cipher_aes_xts, 91 .cf_cipher_prep = cgd_cipher_aes_xts_prep, 92 }, 93 { 94 .cf_name = "aes-cbc", 95 .cf_init = cgd_cipher_aes_cbc_init, 96 .cf_destroy = cgd_cipher_aes_cbc_destroy, 97 .cf_cipher = cgd_cipher_aes_cbc, 98 .cf_cipher_prep = cgd_cipher_aes_cbc_prep, 99 }, 100 { 101 .cf_name = "3des-cbc", 102 .cf_init = cgd_cipher_3des_init, 103 .cf_destroy = cgd_cipher_3des_destroy, 104 .cf_cipher = cgd_cipher_3des_cbc, 105 .cf_cipher_prep = cgd_cipher_3des_cbc_prep, 106 }, 107 { 108 .cf_name = "blowfish-cbc", 109 .cf_init = cgd_cipher_bf_init, 110 .cf_destroy = cgd_cipher_bf_destroy, 111 .cf_cipher = cgd_cipher_bf_cbc, 112 .cf_cipher_prep = cgd_cipher_bf_cbc_prep, 113 }, 114 }; 115 const struct cryptfuncs * 116 cryptfuncs_find(const char *alg) 117 { 118 119 for (size_t i = 0; i < __arraycount(cf); i++) 120 if (strcmp(cf[i].cf_name, alg) == 0) 121 return &cf[i]; 122 123 return NULL; 124 } 125 126 typedef void (*cipher_func)(void *, void *, const void *, size_t); 127 128 static void 129 cgd_cipher_uio(void *privdata, cipher_func cipher, 130 struct uio *dstuio, struct uio *srcuio); 131 132 /* 133 * cgd_cipher_uio takes a simple cbc or xts cipher and iterates 134 * it over two struct uio's. It presumes that the cipher function 135 * that is passed to it keeps the IV state between calls. 136 * 137 * We assume that the caller has ensured that each segment is evenly 138 * divisible by the block size, which for the cgd is a valid assumption. 139 * If we were to make this code more generic, we might need to take care 140 * of this case, either by issuing an error or copying the data. 141 */ 142 143 static void 144 cgd_cipher_uio(void *privdata, cipher_func cipher, 145 struct uio *dstuio, struct uio *srcuio) 146 { 147 const struct iovec *dst; 148 const struct iovec *src; 149 int dstnum; 150 int dstoff = 0; 151 int srcnum; 152 int srcoff = 0; 153 154 dst = dstuio->uio_iov; 155 dstnum = dstuio->uio_iovcnt; 156 src = srcuio->uio_iov; 157 srcnum = srcuio->uio_iovcnt; 158 for (;;) { 159 int l = MIN(dst->iov_len - dstoff, src->iov_len - srcoff); 160 u_int8_t *d = (u_int8_t *)dst->iov_base + dstoff; 161 const u_int8_t *s = (const u_int8_t *)src->iov_base + srcoff; 162 163 cipher(privdata, d, s, l); 164 165 dstoff += l; 166 srcoff += l; 167 /* 168 * We assume that {dst,src} == {dst,src}->iov_len, 169 * because it should not be possible for it not to be. 170 */ 171 if (dstoff == dst->iov_len) { 172 dstoff = 0; 173 dstnum--; 174 dst++; 175 } 176 if (srcoff == src->iov_len) { 177 srcoff = 0; 178 srcnum--; 179 src++; 180 } 181 if (!srcnum || !dstnum) 182 break; 183 } 184 } 185 186 /* 187 * AES Framework 188 */ 189 190 /* 191 * NOTE: we do not store the blocksize in here, because it is not 192 * variable [yet], we hardcode the blocksize to 16 (128 bits). 193 */ 194 195 struct aes_privdata { 196 keyInstance ap_enckey; 197 keyInstance ap_deckey; 198 }; 199 200 struct aes_encdata { 201 keyInstance *ae_key; /* key for this direction */ 202 u_int8_t ae_iv[16]; /* Initialization Vector */ 203 }; 204 205 static void * 206 cgd_cipher_aes_cbc_init(size_t keylen, const void *key, size_t *blocksize) 207 { 208 struct aes_privdata *ap; 209 210 if (!blocksize) 211 return NULL; 212 if (keylen != 128 && keylen != 192 && keylen != 256) 213 return NULL; 214 if (*blocksize == (size_t)-1) 215 *blocksize = 128; 216 if (*blocksize != 128) 217 return NULL; 218 ap = malloc(sizeof(*ap), M_DEVBUF, 0); 219 if (!ap) 220 return NULL; 221 rijndael_makeKey(&ap->ap_enckey, DIR_ENCRYPT, keylen, key); 222 rijndael_makeKey(&ap->ap_deckey, DIR_DECRYPT, keylen, key); 223 return ap; 224 } 225 226 static void 227 cgd_cipher_aes_cbc_destroy(void *data) 228 { 229 struct aes_privdata *apd = data; 230 231 explicit_memset(apd, 0, sizeof(*apd)); 232 free(apd, M_DEVBUF); 233 } 234 235 static void 236 cgd_cipher_aes_cbc_prep(void *privdata, char *iv, 237 const char *blkno_buf, size_t blocksize, int dir) 238 { 239 struct aes_privdata *apd = privdata; 240 cipherInstance cipher; 241 int cipher_ok __diagused; 242 243 cipher_ok = rijndael_cipherInit(&cipher, MODE_CBC, NULL); 244 KASSERT(cipher_ok > 0); 245 rijndael_blockEncrypt(&cipher, &apd->ap_enckey, 246 blkno_buf, blocksize * 8, iv); 247 if (blocksize > 16) 248 (void)memmove(iv, iv + blocksize - 16, 16); 249 } 250 251 static void 252 aes_cbc_enc_int(void *privdata, void *dst, const void *src, size_t len) 253 { 254 struct aes_encdata *ae = privdata; 255 cipherInstance cipher; 256 int cipher_ok __diagused; 257 258 cipher_ok = rijndael_cipherInit(&cipher, MODE_CBC, ae->ae_iv); 259 KASSERT(cipher_ok > 0); 260 rijndael_blockEncrypt(&cipher, ae->ae_key, src, len * 8, dst); 261 (void)memcpy(ae->ae_iv, (u_int8_t *)dst + (len - 16), 16); 262 } 263 264 static void 265 aes_cbc_dec_int(void *privdata, void *dst, const void *src, size_t len) 266 { 267 struct aes_encdata *ae = privdata; 268 cipherInstance cipher; 269 int cipher_ok __diagused; 270 271 cipher_ok = rijndael_cipherInit(&cipher, MODE_CBC, ae->ae_iv); 272 KASSERT(cipher_ok > 0); 273 rijndael_blockDecrypt(&cipher, ae->ae_key, src, len * 8, dst); 274 (void)memcpy(ae->ae_iv, (const u_int8_t *)src + (len - 16), 16); 275 } 276 277 static void 278 cgd_cipher_aes_cbc(void *privdata, struct uio *dstuio, 279 struct uio *srcuio, const void *iv, int dir) 280 { 281 struct aes_privdata *apd = privdata; 282 struct aes_encdata encd; 283 284 (void)memcpy(encd.ae_iv, iv, 16); 285 switch (dir) { 286 case CGD_CIPHER_ENCRYPT: 287 encd.ae_key = &apd->ap_enckey; 288 cgd_cipher_uio(&encd, aes_cbc_enc_int, dstuio, srcuio); 289 break; 290 case CGD_CIPHER_DECRYPT: 291 encd.ae_key = &apd->ap_deckey; 292 cgd_cipher_uio(&encd, aes_cbc_dec_int, dstuio, srcuio); 293 break; 294 default: 295 DIAGPANIC(("%s: unrecognised direction %d", __func__, dir)); 296 } 297 } 298 299 static void * 300 cgd_cipher_aes_xts_init(size_t keylen, const void *xtskey, size_t *blocksize) 301 { 302 struct aes_privdata *ap; 303 const char *key, *key2; /* XTS key is made of two AES keys. */ 304 305 if (!blocksize) 306 return NULL; 307 if (keylen != 256 && keylen != 512) 308 return NULL; 309 if (*blocksize == (size_t)-1) 310 *blocksize = 128; 311 if (*blocksize != 128) 312 return NULL; 313 ap = malloc(2 * sizeof(*ap), M_DEVBUF, 0); 314 if (!ap) 315 return NULL; 316 317 keylen /= 2; 318 key = xtskey; 319 key2 = key + keylen / CHAR_BIT; 320 321 rijndael_makeKey(&ap[0].ap_enckey, DIR_ENCRYPT, keylen, key); 322 rijndael_makeKey(&ap[0].ap_deckey, DIR_DECRYPT, keylen, key); 323 rijndael_makeKey(&ap[1].ap_enckey, DIR_ENCRYPT, keylen, key2); 324 325 return ap; 326 } 327 328 static void 329 cgd_cipher_aes_xts_destroy(void *data) 330 { 331 struct aes_privdata *apd = data; 332 333 explicit_memset(apd, 0, 2 * sizeof(*apd)); 334 free(apd, M_DEVBUF); 335 } 336 337 static void 338 cgd_cipher_aes_xts_prep(void *privdata, char *iv, 339 const char *blkno_buf, size_t blocksize, int dir) 340 { 341 struct aes_privdata *apd = privdata; 342 cipherInstance cipher; 343 int cipher_ok __diagused; 344 345 cipher_ok = rijndael_cipherInit(&cipher, MODE_ECB, NULL); 346 KASSERT(cipher_ok > 0); 347 rijndael_blockEncrypt(&cipher, &apd[1].ap_enckey, 348 blkno_buf, blocksize * 8, iv); 349 } 350 351 static void 352 aes_xts_enc_int(void *privdata, void *dst, const void *src, size_t len) 353 { 354 struct aes_encdata *ae = privdata; 355 cipherInstance cipher; 356 int cipher_ok __diagused; 357 358 cipher_ok = rijndael_cipherInit(&cipher, MODE_XTS, ae->ae_iv); 359 KASSERT(cipher_ok > 0); 360 rijndael_blockEncrypt(&cipher, ae->ae_key, src, len * 8, dst); 361 (void)memcpy(ae->ae_iv, cipher.IV, 16); 362 } 363 364 static void 365 aes_xts_dec_int(void *privdata, void *dst, const void *src, size_t len) 366 { 367 struct aes_encdata *ae = privdata; 368 cipherInstance cipher; 369 int cipher_ok __diagused; 370 371 cipher_ok = rijndael_cipherInit(&cipher, MODE_XTS, ae->ae_iv); 372 KASSERT(cipher_ok > 0); 373 rijndael_blockDecrypt(&cipher, ae->ae_key, src, len * 8, dst); 374 (void)memcpy(ae->ae_iv, cipher.IV, 16); 375 } 376 377 static void 378 cgd_cipher_aes_xts(void *privdata, struct uio *dstuio, 379 struct uio *srcuio, const void *iv, int dir) 380 { 381 struct aes_privdata *apd = privdata; 382 struct aes_encdata encd; 383 384 (void)memcpy(encd.ae_iv, iv, 16); 385 switch (dir) { 386 case CGD_CIPHER_ENCRYPT: 387 encd.ae_key = &apd->ap_enckey; 388 cgd_cipher_uio(&encd, aes_xts_enc_int, dstuio, srcuio); 389 break; 390 case CGD_CIPHER_DECRYPT: 391 encd.ae_key = &apd->ap_deckey; 392 cgd_cipher_uio(&encd, aes_xts_dec_int, dstuio, srcuio); 393 break; 394 default: 395 DIAGPANIC(("%s: unrecognised direction %d", __func__, dir)); 396 } 397 } 398 399 /* 400 * 3DES Framework 401 */ 402 403 struct c3des_privdata { 404 des_key_schedule cp_key1; 405 des_key_schedule cp_key2; 406 des_key_schedule cp_key3; 407 }; 408 409 struct c3des_encdata { 410 des_key_schedule *ce_key1; 411 des_key_schedule *ce_key2; 412 des_key_schedule *ce_key3; 413 u_int8_t ce_iv[8]; 414 }; 415 416 static void * 417 cgd_cipher_3des_init(size_t keylen, const void *key, size_t *blocksize) 418 { 419 struct c3des_privdata *cp; 420 int error = 0; 421 des_cblock *block; 422 423 if (!blocksize) 424 return NULL; 425 if (*blocksize == (size_t)-1) 426 *blocksize = 64; 427 if (keylen != (DES_KEY_SZ * 3 * 8) || *blocksize != 64) 428 return NULL; 429 cp = malloc(sizeof(*cp), M_DEVBUF, 0); 430 if (!cp) 431 return NULL; 432 block = __UNCONST(key); 433 error = des_key_sched(block, cp->cp_key1); 434 error |= des_key_sched(block + 1, cp->cp_key2); 435 error |= des_key_sched(block + 2, cp->cp_key3); 436 if (error) { 437 explicit_memset(cp, 0, sizeof(*cp)); 438 free(cp, M_DEVBUF); 439 return NULL; 440 } 441 return cp; 442 } 443 444 static void 445 cgd_cipher_3des_destroy(void *data) 446 { 447 struct c3des_privdata *cp = data; 448 449 explicit_memset(cp, 0, sizeof(*cp)); 450 free(cp, M_DEVBUF); 451 } 452 453 static void 454 cgd_cipher_3des_cbc_prep(void *privdata, char *iv, 455 const char *blkno_buf, size_t blocksize, int dir) 456 { 457 struct c3des_privdata *cp = privdata; 458 char zero_iv[8]; 459 460 memset(zero_iv, 0, sizeof(zero_iv)); 461 des_ede3_cbc_encrypt(blkno_buf, iv, blocksize, 462 cp->cp_key1, cp->cp_key2, cp->cp_key3, (des_cblock *)zero_iv, 1); 463 if (blocksize > 8) 464 (void)memmove(iv, iv + blocksize - 8, 8); 465 } 466 467 static void 468 c3des_cbc_enc_int(void *privdata, void *dst, const void *src, size_t len) 469 { 470 struct c3des_encdata *ce = privdata; 471 472 des_ede3_cbc_encrypt(src, dst, len, *ce->ce_key1, *ce->ce_key2, 473 *ce->ce_key3, (des_cblock *)ce->ce_iv, 1); 474 (void)memcpy(ce->ce_iv, (const u_int8_t *)dst + (len - 8), 8); 475 } 476 477 static void 478 c3des_cbc_dec_int(void *privdata, void *dst, const void *src, size_t len) 479 { 480 struct c3des_encdata *ce = privdata; 481 482 des_ede3_cbc_encrypt(src, dst, len, *ce->ce_key1, *ce->ce_key2, 483 *ce->ce_key3, (des_cblock *)ce->ce_iv, 0); 484 (void)memcpy(ce->ce_iv, (const u_int8_t *)src + (len - 8), 8); 485 } 486 487 static void 488 cgd_cipher_3des_cbc(void *privdata, struct uio *dstuio, 489 struct uio *srcuio, const void *iv, int dir) 490 { 491 struct c3des_privdata *cp = privdata; 492 struct c3des_encdata ce; 493 494 (void)memcpy(ce.ce_iv, iv, 8); 495 ce.ce_key1 = &cp->cp_key1; 496 ce.ce_key2 = &cp->cp_key2; 497 ce.ce_key3 = &cp->cp_key3; 498 switch (dir) { 499 case CGD_CIPHER_ENCRYPT: 500 cgd_cipher_uio(&ce, c3des_cbc_enc_int, dstuio, srcuio); 501 break; 502 case CGD_CIPHER_DECRYPT: 503 cgd_cipher_uio(&ce, c3des_cbc_dec_int, dstuio, srcuio); 504 break; 505 default: 506 DIAGPANIC(("%s: unrecognised direction %d", __func__, dir)); 507 } 508 } 509 510 /* 511 * Blowfish Framework 512 */ 513 514 struct bf_privdata { 515 BF_KEY bp_key; 516 }; 517 518 struct bf_encdata { 519 BF_KEY *be_key; 520 u_int8_t be_iv[8]; 521 }; 522 523 static void * 524 cgd_cipher_bf_init(size_t keylen, const void *key, size_t *blocksize) 525 { 526 struct bf_privdata *bp; 527 528 if (!blocksize) 529 return NULL; 530 if (keylen < 40 || keylen > 448 || (keylen % 8 != 0)) 531 return NULL; 532 if (*blocksize == (size_t)-1) 533 *blocksize = 64; 534 if (*blocksize != 64) 535 return NULL; 536 bp = malloc(sizeof(*bp), M_DEVBUF, 0); 537 if (!bp) 538 return NULL; 539 BF_set_key(&bp->bp_key, keylen / 8, key); 540 return bp; 541 } 542 543 static void 544 cgd_cipher_bf_destroy(void *data) 545 { 546 struct bf_privdata *bp = data; 547 548 explicit_memset(bp, 0, sizeof(*bp)); 549 free(bp, M_DEVBUF); 550 } 551 552 static void 553 cgd_cipher_bf_cbc_prep(void *privdata, char *iv, 554 const char *blkno_buf, size_t blocksize, int dir) 555 { 556 struct bf_privdata *bp = privdata; 557 char zero_iv[8]; 558 559 memset(zero_iv, 0, sizeof(zero_iv)); 560 BF_cbc_encrypt(blkno_buf, iv, blocksize, &bp->bp_key, zero_iv, 1); 561 if (blocksize > 8) 562 (void)memmove(iv, iv + blocksize - 8, 8); 563 } 564 565 static void 566 bf_cbc_enc_int(void *privdata, void *dst, const void *src, size_t len) 567 { 568 struct bf_encdata *be = privdata; 569 570 BF_cbc_encrypt(src, dst, len, be->be_key, be->be_iv, 1); 571 (void)memcpy(be->be_iv, (u_int8_t *)dst + (len - 8), 8); 572 } 573 574 static void 575 bf_cbc_dec_int(void *privdata, void *dst, const void *src, size_t len) 576 { 577 struct bf_encdata *be = privdata; 578 579 BF_cbc_encrypt(src, dst, len, be->be_key, be->be_iv, 0); 580 (void)memcpy(be->be_iv, (const u_int8_t *)src + (len - 8), 8); 581 } 582 583 static void 584 cgd_cipher_bf_cbc(void *privdata, struct uio *dstuio, 585 struct uio *srcuio, const void *iv, int dir) 586 { 587 struct bf_privdata *bp = privdata; 588 struct bf_encdata be; 589 590 (void)memcpy(be.be_iv, iv, 8); 591 be.be_key = &bp->bp_key; 592 switch (dir) { 593 case CGD_CIPHER_ENCRYPT: 594 cgd_cipher_uio(&be, bf_cbc_enc_int, dstuio, srcuio); 595 break; 596 case CGD_CIPHER_DECRYPT: 597 cgd_cipher_uio(&be, bf_cbc_dec_int, dstuio, srcuio); 598 break; 599 default: 600 DIAGPANIC(("%s: unrecognised direction %d", __func__, dir)); 601 } 602 603 } 604