Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/crypto: enable clear key values for paes ciphers

With this patch the paes ciphers do accept AES clear key values of
size 16, 24 or 32 byte. The key value is internal rearranged to form a
paes clear key token so that the pkey kernel module recognizes and
handles this key material as source for protected keys.

Using clear key material as a source for protected keys is a security
risc as the raw key material is kept in memory. However, so the AES
selftests provided with the testmanager can be run during registration
of the paes ciphers.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>

authored by

Harald Freudenberger and committed by
Vasily Gorbik
7f820d05 888edbc4

+48 -21
+48 -21
arch/s390/crypto/paes_s390.c
··· 33 33 * is called. As paes can handle different kinds of key blobs 34 34 * and padding is also possible, the limits need to be generous. 35 35 */ 36 - #define PAES_MIN_KEYSIZE 64 36 + #define PAES_MIN_KEYSIZE 16 37 37 #define PAES_MAX_KEYSIZE 256 38 38 39 39 static u8 *ctrblk; ··· 54 54 unsigned int keylen; 55 55 }; 56 56 57 - static inline int _copy_key_to_kb(struct key_blob *kb, 58 - const u8 *key, 59 - unsigned int keylen) 57 + static inline int _key_to_kb(struct key_blob *kb, 58 + const u8 *key, 59 + unsigned int keylen) 60 60 { 61 - if (keylen <= sizeof(kb->keybuf)) 61 + struct clearkey_header { 62 + u8 type; 63 + u8 res0[3]; 64 + u8 version; 65 + u8 res1[3]; 66 + u32 keytype; 67 + u32 len; 68 + } __packed * h; 69 + 70 + switch (keylen) { 71 + case 16: 72 + case 24: 73 + case 32: 74 + /* clear key value, prepare pkey clear key token in keybuf */ 75 + memset(kb->keybuf, 0, sizeof(kb->keybuf)); 76 + h = (struct clearkey_header *) kb->keybuf; 77 + h->version = 0x02; /* TOKVER_CLEAR_KEY */ 78 + h->keytype = (keylen - 8) >> 3; 79 + h->len = keylen; 80 + memcpy(kb->keybuf + sizeof(*h), key, keylen); 81 + kb->keylen = sizeof(*h) + keylen; 62 82 kb->key = kb->keybuf; 63 - else { 64 - kb->key = kmalloc(keylen, GFP_KERNEL); 65 - if (!kb->key) 66 - return -ENOMEM; 83 + break; 84 + default: 85 + /* other key material, let pkey handle this */ 86 + if (keylen <= sizeof(kb->keybuf)) 87 + kb->key = kb->keybuf; 88 + else { 89 + kb->key = kmalloc(keylen, GFP_KERNEL); 90 + if (!kb->key) 91 + return -ENOMEM; 92 + } 93 + memcpy(kb->key, key, keylen); 94 + kb->keylen = keylen; 95 + break; 67 96 } 68 - memcpy(kb->key, key, keylen); 69 - kb->keylen = keylen; 70 97 71 98 return 0; 72 99 } ··· 192 165 struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm); 193 166 194 167 _free_kb_keybuf(&ctx->kb); 195 - rc = _copy_key_to_kb(&ctx->kb, in_key, key_len); 168 + rc = _key_to_kb(&ctx->kb, in_key, key_len); 196 169 if (rc) 197 170 return rc; 198 171 ··· 305 278 struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm); 306 279 307 280 _free_kb_keybuf(&ctx->kb); 308 - rc = _copy_key_to_kb(&ctx->kb, in_key, key_len); 281 + rc = _key_to_kb(&ctx->kb, in_key, key_len); 309 282 if (rc) 310 283 return rc; 311 284 ··· 452 425 453 426 _free_kb_keybuf(&ctx->kb[0]); 454 427 _free_kb_keybuf(&ctx->kb[1]); 455 - rc = _copy_key_to_kb(&ctx->kb[0], in_key, key_len); 428 + rc = _key_to_kb(&ctx->kb[0], in_key, key_len); 456 429 if (rc) 457 430 return rc; 458 - rc = _copy_key_to_kb(&ctx->kb[1], in_key + key_len, key_len); 431 + rc = _key_to_kb(&ctx->kb[1], in_key + key_len, key_len); 459 432 if (rc) 460 433 return rc; 461 434 ··· 601 574 struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm); 602 575 603 576 _free_kb_keybuf(&ctx->kb); 604 - rc = _copy_key_to_kb(&ctx->kb, in_key, key_len); 577 + rc = _key_to_kb(&ctx->kb, in_key, key_len); 605 578 if (rc) 606 579 return rc; 607 580 ··· 722 695 723 696 static void paes_s390_fini(void) 724 697 { 725 - if (ctrblk) 726 - free_page((unsigned long) ctrblk); 727 698 __crypto_unregister_skcipher(&ctr_paes_alg); 728 699 __crypto_unregister_skcipher(&xts_paes_alg); 729 700 __crypto_unregister_skcipher(&cbc_paes_alg); 730 701 __crypto_unregister_skcipher(&ecb_paes_alg); 702 + if (ctrblk) 703 + free_page((unsigned long) ctrblk); 731 704 } 732 705 733 706 static int __init paes_s390_init(void) ··· 765 738 if (cpacf_test_func(&kmctr_functions, CPACF_KMCTR_PAES_128) || 766 739 cpacf_test_func(&kmctr_functions, CPACF_KMCTR_PAES_192) || 767 740 cpacf_test_func(&kmctr_functions, CPACF_KMCTR_PAES_256)) { 768 - ret = crypto_register_skcipher(&ctr_paes_alg); 769 - if (ret) 770 - goto out_err; 771 741 ctrblk = (u8 *) __get_free_page(GFP_KERNEL); 772 742 if (!ctrblk) { 773 743 ret = -ENOMEM; 774 744 goto out_err; 775 745 } 746 + ret = crypto_register_skcipher(&ctr_paes_alg); 747 + if (ret) 748 + goto out_err; 776 749 } 777 750 778 751 return 0;