Back to home page

OSCL-LXR

 
 

    


0001 /* Orinoco MIC helpers
0002  *
0003  * See copyright notice in main.c
0004  */
0005 #include <linux/kernel.h>
0006 #include <linux/string.h>
0007 #include <linux/if_ether.h>
0008 #include <linux/scatterlist.h>
0009 #include <crypto/hash.h>
0010 
0011 #include "orinoco.h"
0012 #include "mic.h"
0013 
0014 /********************************************************************/
0015 /* Michael MIC crypto setup                                         */
0016 /********************************************************************/
0017 int orinoco_mic_init(struct orinoco_private *priv)
0018 {
0019     priv->tx_tfm_mic = crypto_alloc_shash("michael_mic", 0, 0);
0020     if (IS_ERR(priv->tx_tfm_mic)) {
0021         printk(KERN_DEBUG "%s: could not allocate "
0022                "crypto API michael_mic\n", __func__);
0023         priv->tx_tfm_mic = NULL;
0024         return -ENOMEM;
0025     }
0026 
0027     priv->rx_tfm_mic = crypto_alloc_shash("michael_mic", 0, 0);
0028     if (IS_ERR(priv->rx_tfm_mic)) {
0029         printk(KERN_DEBUG "%s: could not allocate "
0030                "crypto API michael_mic\n", __func__);
0031         priv->rx_tfm_mic = NULL;
0032         return -ENOMEM;
0033     }
0034 
0035     return 0;
0036 }
0037 
0038 void orinoco_mic_free(struct orinoco_private *priv)
0039 {
0040     if (priv->tx_tfm_mic)
0041         crypto_free_shash(priv->tx_tfm_mic);
0042     if (priv->rx_tfm_mic)
0043         crypto_free_shash(priv->rx_tfm_mic);
0044 }
0045 
0046 int orinoco_mic(struct crypto_shash *tfm_michael, u8 *key,
0047         u8 *da, u8 *sa, u8 priority,
0048         u8 *data, size_t data_len, u8 *mic)
0049 {
0050     SHASH_DESC_ON_STACK(desc, tfm_michael);
0051     u8 hdr[ETH_HLEN + 2]; /* size of header + padding */
0052     int err;
0053 
0054     if (tfm_michael == NULL) {
0055         printk(KERN_WARNING "%s: tfm_michael == NULL\n", __func__);
0056         return -1;
0057     }
0058 
0059     /* Copy header into buffer. We need the padding on the end zeroed */
0060     memcpy(&hdr[0], da, ETH_ALEN);
0061     memcpy(&hdr[ETH_ALEN], sa, ETH_ALEN);
0062     hdr[ETH_ALEN * 2] = priority;
0063     hdr[ETH_ALEN * 2 + 1] = 0;
0064     hdr[ETH_ALEN * 2 + 2] = 0;
0065     hdr[ETH_ALEN * 2 + 3] = 0;
0066 
0067     desc->tfm = tfm_michael;
0068 
0069     err = crypto_shash_setkey(tfm_michael, key, MIC_KEYLEN);
0070     if (err)
0071         return err;
0072 
0073     err = crypto_shash_init(desc);
0074     if (err)
0075         return err;
0076 
0077     err = crypto_shash_update(desc, hdr, sizeof(hdr));
0078     if (err)
0079         return err;
0080 
0081     err = crypto_shash_update(desc, data, data_len);
0082     if (err)
0083         return err;
0084 
0085     err = crypto_shash_final(desc, mic);
0086     shash_desc_zero(desc);
0087 
0088     return err;
0089 }