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

Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6

Pull crypto fixes from Herbert Xu:
"Fix a number of bugs in the ccp driver"

* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6:
crypto: ccp - Ignore tag length when decrypting GCM ciphertext
crypto: ccp - Add support for valid authsize values less than 16
crypto: ccp - Fix oops by properly managing allocated structures

+40 -9
+14
drivers/crypto/ccp/ccp-crypto-aes-galois.c
··· 58 58 static int ccp_aes_gcm_setauthsize(struct crypto_aead *tfm, 59 59 unsigned int authsize) 60 60 { 61 + switch (authsize) { 62 + case 16: 63 + case 15: 64 + case 14: 65 + case 13: 66 + case 12: 67 + case 8: 68 + case 4: 69 + break; 70 + default: 71 + return -EINVAL; 72 + } 73 + 61 74 return 0; 62 75 } 63 76 ··· 117 104 memset(&rctx->cmd, 0, sizeof(rctx->cmd)); 118 105 INIT_LIST_HEAD(&rctx->cmd.entry); 119 106 rctx->cmd.engine = CCP_ENGINE_AES; 107 + rctx->cmd.u.aes.authsize = crypto_aead_authsize(tfm); 120 108 rctx->cmd.u.aes.type = ctx->u.aes.type; 121 109 rctx->cmd.u.aes.mode = ctx->u.aes.mode; 122 110 rctx->cmd.u.aes.action = encrypt;
+24 -9
drivers/crypto/ccp/ccp-ops.c
··· 622 622 623 623 unsigned long long *final; 624 624 unsigned int dm_offset; 625 + unsigned int authsize; 625 626 unsigned int jobid; 626 627 unsigned int ilen; 627 628 bool in_place = true; /* Default value */ ··· 644 643 if (!aes->key) /* Gotta have a key SGL */ 645 644 return -EINVAL; 646 645 646 + /* Zero defaults to 16 bytes, the maximum size */ 647 + authsize = aes->authsize ? aes->authsize : AES_BLOCK_SIZE; 648 + switch (authsize) { 649 + case 16: 650 + case 15: 651 + case 14: 652 + case 13: 653 + case 12: 654 + case 8: 655 + case 4: 656 + break; 657 + default: 658 + return -EINVAL; 659 + } 660 + 647 661 /* First, decompose the source buffer into AAD & PT, 648 662 * and the destination buffer into AAD, CT & tag, or 649 663 * the input into CT & tag. ··· 673 657 p_tag = scatterwalk_ffwd(sg_tag, p_outp, ilen); 674 658 } else { 675 659 /* Input length for decryption includes tag */ 676 - ilen = aes->src_len - AES_BLOCK_SIZE; 660 + ilen = aes->src_len - authsize; 677 661 p_tag = scatterwalk_ffwd(sg_tag, p_inp, ilen); 678 662 } 679 663 ··· 782 766 while (src.sg_wa.bytes_left) { 783 767 ccp_prepare_data(&src, &dst, &op, AES_BLOCK_SIZE, true); 784 768 if (!src.sg_wa.bytes_left) { 785 - unsigned int nbytes = aes->src_len 786 - % AES_BLOCK_SIZE; 769 + unsigned int nbytes = ilen % AES_BLOCK_SIZE; 787 770 788 771 if (nbytes) { 789 772 op.eom = 1; ··· 854 839 855 840 if (aes->action == CCP_AES_ACTION_ENCRYPT) { 856 841 /* Put the ciphered tag after the ciphertext. */ 857 - ccp_get_dm_area(&final_wa, 0, p_tag, 0, AES_BLOCK_SIZE); 842 + ccp_get_dm_area(&final_wa, 0, p_tag, 0, authsize); 858 843 } else { 859 844 /* Does this ciphered tag match the input? */ 860 - ret = ccp_init_dm_workarea(&tag, cmd_q, AES_BLOCK_SIZE, 845 + ret = ccp_init_dm_workarea(&tag, cmd_q, authsize, 861 846 DMA_BIDIRECTIONAL); 862 847 if (ret) 863 848 goto e_tag; 864 - ret = ccp_set_dm_area(&tag, 0, p_tag, 0, AES_BLOCK_SIZE); 849 + ret = ccp_set_dm_area(&tag, 0, p_tag, 0, authsize); 865 850 if (ret) 866 851 goto e_tag; 867 852 868 853 ret = crypto_memneq(tag.address, final_wa.address, 869 - AES_BLOCK_SIZE) ? -EBADMSG : 0; 854 + authsize) ? -EBADMSG : 0; 870 855 ccp_dm_free(&tag); 871 856 } 872 857 ··· 874 859 ccp_dm_free(&final_wa); 875 860 876 861 e_dst: 877 - if (aes->src_len && !in_place) 862 + if (ilen > 0 && !in_place) 878 863 ccp_free_data(&dst, cmd_q); 879 864 880 865 e_src: 881 - if (aes->src_len) 866 + if (ilen > 0) 882 867 ccp_free_data(&src, cmd_q); 883 868 884 869 e_aad:
+2
include/linux/ccp.h
··· 170 170 enum ccp_aes_mode mode; 171 171 enum ccp_aes_action action; 172 172 173 + u32 authsize; 174 + 173 175 struct scatterlist *key; 174 176 u32 key_len; /* In bytes */ 175 177