diff options
Diffstat (limited to 'drivers/usb/wusbcore')
-rw-r--r-- | drivers/usb/wusbcore/crypto.c | 61 | ||||
-rw-r--r-- | drivers/usb/wusbcore/dev-sysfs.c | 6 | ||||
-rw-r--r-- | drivers/usb/wusbcore/wusbhc.c | 13 |
3 files changed, 47 insertions, 33 deletions
diff --git a/drivers/usb/wusbcore/crypto.c b/drivers/usb/wusbcore/crypto.c index 79b2b628066d..79451f7ef1b7 100644 --- a/drivers/usb/wusbcore/crypto.c +++ b/drivers/usb/wusbcore/crypto.c @@ -133,6 +133,13 @@ static void bytewise_xor(void *_bo, const void *_bi1, const void *_bi2, bo[itr] = bi1[itr] ^ bi2[itr]; } +/* Scratch space for MAC calculations. */ +struct wusb_mac_scratch { + struct aes_ccm_b0 b0; + struct aes_ccm_b1 b1; + struct aes_ccm_a ax; +}; + /* * CC-MAC function WUSB1.0[6.5] * @@ -197,16 +204,15 @@ static void bytewise_xor(void *_bo, const void *_bi1, const void *_bi2, * what sg[4] is for. Maybe there is a smarter way to do this. */ static int wusb_ccm_mac(struct crypto_skcipher *tfm_cbc, - struct crypto_cipher *tfm_aes, void *mic, + struct crypto_cipher *tfm_aes, + struct wusb_mac_scratch *scratch, + void *mic, const struct aes_ccm_nonce *n, const struct aes_ccm_label *a, const void *b, size_t blen) { int result = 0; SKCIPHER_REQUEST_ON_STACK(req, tfm_cbc); - struct aes_ccm_b0 b0; - struct aes_ccm_b1 b1; - struct aes_ccm_a ax; struct scatterlist sg[4], sg_dst; void *dst_buf; size_t dst_size; @@ -218,16 +224,17 @@ static int wusb_ccm_mac(struct crypto_skcipher *tfm_cbc, * These checks should be compile time optimized out * ensure @a fills b1's mac_header and following fields */ - WARN_ON(sizeof(*a) != sizeof(b1) - sizeof(b1.la)); - WARN_ON(sizeof(b0) != sizeof(struct aes_ccm_block)); - WARN_ON(sizeof(b1) != sizeof(struct aes_ccm_block)); - WARN_ON(sizeof(ax) != sizeof(struct aes_ccm_block)); + WARN_ON(sizeof(*a) != sizeof(scratch->b1) - sizeof(scratch->b1.la)); + WARN_ON(sizeof(scratch->b0) != sizeof(struct aes_ccm_block)); + WARN_ON(sizeof(scratch->b1) != sizeof(struct aes_ccm_block)); + WARN_ON(sizeof(scratch->ax) != sizeof(struct aes_ccm_block)); result = -ENOMEM; zero_padding = blen % sizeof(struct aes_ccm_block); if (zero_padding) zero_padding = sizeof(struct aes_ccm_block) - zero_padding; - dst_size = blen + sizeof(b0) + sizeof(b1) + zero_padding; + dst_size = blen + sizeof(scratch->b0) + sizeof(scratch->b1) + + zero_padding; dst_buf = kzalloc(dst_size, GFP_KERNEL); if (!dst_buf) goto error_dst_buf; @@ -235,9 +242,9 @@ static int wusb_ccm_mac(struct crypto_skcipher *tfm_cbc, memset(iv, 0, sizeof(iv)); /* Setup B0 */ - b0.flags = 0x59; /* Format B0 */ - b0.ccm_nonce = *n; - b0.lm = cpu_to_be16(0); /* WUSB1.0[6.5] sez l(m) is 0 */ + scratch->b0.flags = 0x59; /* Format B0 */ + scratch->b0.ccm_nonce = *n; + scratch->b0.lm = cpu_to_be16(0); /* WUSB1.0[6.5] sez l(m) is 0 */ /* Setup B1 * @@ -246,12 +253,12 @@ static int wusb_ccm_mac(struct crypto_skcipher *tfm_cbc, * 14'--after clarification, it means to use A's contents * for MAC Header, EO, sec reserved and padding. */ - b1.la = cpu_to_be16(blen + 14); - memcpy(&b1.mac_header, a, sizeof(*a)); + scratch->b1.la = cpu_to_be16(blen + 14); + memcpy(&scratch->b1.mac_header, a, sizeof(*a)); sg_init_table(sg, ARRAY_SIZE(sg)); - sg_set_buf(&sg[0], &b0, sizeof(b0)); - sg_set_buf(&sg[1], &b1, sizeof(b1)); + sg_set_buf(&sg[0], &scratch->b0, sizeof(scratch->b0)); + sg_set_buf(&sg[1], &scratch->b1, sizeof(scratch->b1)); sg_set_buf(&sg[2], b, blen); /* 0 if well behaved :) */ sg_set_buf(&sg[3], bzero, zero_padding); @@ -276,11 +283,12 @@ static int wusb_ccm_mac(struct crypto_skcipher *tfm_cbc, * POS Crypto API: size is assumed to be AES's block size. * Thanks for documenting it -- tip taken from airo.c */ - ax.flags = 0x01; /* as per WUSB 1.0 spec */ - ax.ccm_nonce = *n; - ax.counter = 0; - crypto_cipher_encrypt_one(tfm_aes, (void *)&ax, (void *)&ax); - bytewise_xor(mic, &ax, iv, 8); + scratch->ax.flags = 0x01; /* as per WUSB 1.0 spec */ + scratch->ax.ccm_nonce = *n; + scratch->ax.counter = 0; + crypto_cipher_encrypt_one(tfm_aes, (void *)&scratch->ax, + (void *)&scratch->ax); + bytewise_xor(mic, &scratch->ax, iv, 8); result = 8; error_cbc_crypt: kfree(dst_buf); @@ -303,6 +311,7 @@ ssize_t wusb_prf(void *out, size_t out_size, struct aes_ccm_nonce n = *_n; struct crypto_skcipher *tfm_cbc; struct crypto_cipher *tfm_aes; + struct wusb_mac_scratch *scratch; u64 sfn = 0; __le64 sfn_le; @@ -329,17 +338,25 @@ ssize_t wusb_prf(void *out, size_t out_size, printk(KERN_ERR "E: can't set AES key: %d\n", (int)result); goto error_setkey_aes; } + scratch = kmalloc(sizeof(*scratch), GFP_KERNEL); + if (!scratch) { + result = -ENOMEM; + goto error_alloc_scratch; + } for (bitr = 0; bitr < (len + 63) / 64; bitr++) { sfn_le = cpu_to_le64(sfn++); memcpy(&n.sfn, &sfn_le, sizeof(n.sfn)); /* n.sfn++... */ - result = wusb_ccm_mac(tfm_cbc, tfm_aes, out + bytes, + result = wusb_ccm_mac(tfm_cbc, tfm_aes, scratch, out + bytes, &n, a, b, blen); if (result < 0) goto error_ccm_mac; bytes += result; } result = bytes; + + kfree(scratch); +error_alloc_scratch: error_ccm_mac: error_setkey_aes: crypto_free_cipher(tfm_aes); diff --git a/drivers/usb/wusbcore/dev-sysfs.c b/drivers/usb/wusbcore/dev-sysfs.c index 415b14002a61..d4de56b93d68 100644 --- a/drivers/usb/wusbcore/dev-sysfs.c +++ b/drivers/usb/wusbcore/dev-sysfs.c @@ -53,7 +53,7 @@ static ssize_t wusb_disconnect_store(struct device *dev, wusbhc_put(wusbhc); return size; } -static DEVICE_ATTR(wusb_disconnect, 0200, NULL, wusb_disconnect_store); +static DEVICE_ATTR_WO(wusb_disconnect); static ssize_t wusb_cdid_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -69,7 +69,7 @@ static ssize_t wusb_cdid_show(struct device *dev, wusb_dev_put(wusb_dev); return result + 1; } -static DEVICE_ATTR(wusb_cdid, 0444, wusb_cdid_show, NULL); +static DEVICE_ATTR_RO(wusb_cdid); static ssize_t wusb_ck_store(struct device *dev, struct device_attribute *attr, @@ -105,7 +105,7 @@ static ssize_t wusb_ck_store(struct device *dev, wusbhc_put(wusbhc); return result < 0 ? result : size; } -static DEVICE_ATTR(wusb_ck, 0200, NULL, wusb_ck_store); +static DEVICE_ATTR_WO(wusb_ck); static struct attribute *wusb_dev_attrs[] = { &dev_attr_wusb_disconnect.attr, diff --git a/drivers/usb/wusbcore/wusbhc.c b/drivers/usb/wusbcore/wusbhc.c index 94f401ab859f..a273a91cf667 100644 --- a/drivers/usb/wusbcore/wusbhc.c +++ b/drivers/usb/wusbcore/wusbhc.c @@ -84,8 +84,7 @@ static ssize_t wusb_trust_timeout_store(struct device *dev, out: return result < 0 ? result : size; } -static DEVICE_ATTR(wusb_trust_timeout, 0644, wusb_trust_timeout_show, - wusb_trust_timeout_store); +static DEVICE_ATTR_RW(wusb_trust_timeout); /* * Show the current WUSB CHID. @@ -145,7 +144,7 @@ static ssize_t wusb_chid_store(struct device *dev, result = wusbhc_chid_set(wusbhc, &chid); return result < 0 ? result : size; } -static DEVICE_ATTR(wusb_chid, 0644, wusb_chid_show, wusb_chid_store); +static DEVICE_ATTR_RW(wusb_chid); static ssize_t wusb_phy_rate_show(struct device *dev, @@ -174,8 +173,7 @@ static ssize_t wusb_phy_rate_store(struct device *dev, wusbhc->phy_rate = phy_rate; return size; } -static DEVICE_ATTR(wusb_phy_rate, 0644, wusb_phy_rate_show, - wusb_phy_rate_store); +static DEVICE_ATTR_RW(wusb_phy_rate); static ssize_t wusb_dnts_show(struct device *dev, struct device_attribute *attr, @@ -205,7 +203,7 @@ static ssize_t wusb_dnts_store(struct device *dev, return size; } -static DEVICE_ATTR(wusb_dnts, 0644, wusb_dnts_show, wusb_dnts_store); +static DEVICE_ATTR_RW(wusb_dnts); static ssize_t wusb_retry_count_show(struct device *dev, struct device_attribute *attr, @@ -234,8 +232,7 @@ static ssize_t wusb_retry_count_store(struct device *dev, return size; } -static DEVICE_ATTR(wusb_retry_count, 0644, wusb_retry_count_show, - wusb_retry_count_store); +static DEVICE_ATTR_RW(wusb_retry_count); /* Group all the WUSBHC attributes */ static struct attribute *wusbhc_attrs[] = { |