diff options
Diffstat (limited to 'target/linux/generic-2.4/files/crypto/ocf/cryptocteon/cryptocteon.c')
-rw-r--r-- | target/linux/generic-2.4/files/crypto/ocf/cryptocteon/cryptocteon.c | 574 |
1 files changed, 0 insertions, 574 deletions
diff --git a/target/linux/generic-2.4/files/crypto/ocf/cryptocteon/cryptocteon.c b/target/linux/generic-2.4/files/crypto/ocf/cryptocteon/cryptocteon.c deleted file mode 100644 index 9940f59a9a..0000000000 --- a/target/linux/generic-2.4/files/crypto/ocf/cryptocteon/cryptocteon.c +++ /dev/null @@ -1,574 +0,0 @@ -/* - * Octeon Crypto for OCF - * - * Written by David McCullough <david_mccullough@mcafee.com> - * Copyright (C) 2009-2010 David McCullough - * - * LICENSE TERMS - * - * The free distribution and use of this software in both source and binary - * form is allowed (with or without changes) provided that: - * - * 1. distributions of this source code include the above copyright - * notice, this list of conditions and the following disclaimer; - * - * 2. distributions in binary form include the above copyright - * notice, this list of conditions and the following disclaimer - * in the documentation and/or other associated materials; - * - * 3. the copyright holder's name is not used to endorse products - * built using this software without specific written permission. - * - * DISCLAIMER - * - * This software is provided 'as is' with no explicit or implied warranties - * in respect of its properties, including, but not limited to, correctness - * and/or fitness for purpose. - * --------------------------------------------------------------------------- - */ - -#ifndef AUTOCONF_INCLUDED -#include <linux/config.h> -#endif -#include <linux/module.h> -#include <linux/init.h> -#include <linux/list.h> -#include <linux/slab.h> -#include <linux/sched.h> -#include <linux/wait.h> -#include <linux/crypto.h> -#include <linux/mm.h> -#include <linux/skbuff.h> -#include <linux/random.h> -#include <linux/scatterlist.h> - -#include <cryptodev.h> -#include <uio.h> - -struct { - softc_device_decl sc_dev; -} octo_softc; - -#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK) - -struct octo_sess { - int octo_encalg; - #define MAX_CIPHER_KEYLEN 64 - char octo_enckey[MAX_CIPHER_KEYLEN]; - int octo_encklen; - - int octo_macalg; - #define MAX_HASH_KEYLEN 64 - char octo_mackey[MAX_HASH_KEYLEN]; - int octo_macklen; - int octo_mackey_set; - - int octo_mlen; - int octo_ivsize; - -#if 0 - int (*octo_decrypt)(struct scatterlist *sg, int sg_len, - uint8_t *key, int key_len, uint8_t * iv, - uint64_t *hminner, uint64_t *hmouter); - - int (*octo_encrypt)(struct scatterlist *sg, int sg_len, - uint8_t *key, int key_len, uint8_t * iv, - uint64_t *hminner, uint64_t *hmouter); -#else - int (*octo_encrypt)(struct octo_sess *od, - struct scatterlist *sg, int sg_len, - int auth_off, int auth_len, - int crypt_off, int crypt_len, - int icv_off, uint8_t *ivp); - int (*octo_decrypt)(struct octo_sess *od, - struct scatterlist *sg, int sg_len, - int auth_off, int auth_len, - int crypt_off, int crypt_len, - int icv_off, uint8_t *ivp); -#endif - - uint64_t octo_hminner[3]; - uint64_t octo_hmouter[3]; -}; - -int32_t octo_id = -1; -module_param(octo_id, int, 0444); -MODULE_PARM_DESC(octo_id, "Read-Only OCF ID for cryptocteon driver"); - -static struct octo_sess **octo_sessions = NULL; -static u_int32_t octo_sesnum = 0; - -static int octo_process(device_t, struct cryptop *, int); -static int octo_newsession(device_t, u_int32_t *, struct cryptoini *); -static int octo_freesession(device_t, u_int64_t); - -static device_method_t octo_methods = { - /* crypto device methods */ - DEVMETHOD(cryptodev_newsession, octo_newsession), - DEVMETHOD(cryptodev_freesession,octo_freesession), - DEVMETHOD(cryptodev_process, octo_process), -}; - -#define debug octo_debug -int octo_debug = 0; -module_param(octo_debug, int, 0644); -MODULE_PARM_DESC(octo_debug, "Enable debug"); - - -#include "cavium_crypto.c" - - -/* - * Generate a new octo session. We artifically limit it to a single - * hash/cipher or hash-cipher combo just to make it easier, most callers - * do not expect more than this anyway. - */ -static int -octo_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri) -{ - struct cryptoini *c, *encini = NULL, *macini = NULL; - struct octo_sess **ocd; - int i; - - dprintk("%s()\n", __FUNCTION__); - if (sid == NULL || cri == NULL) { - dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__); - return EINVAL; - } - - /* - * To keep it simple, we only handle hash, cipher or hash/cipher in a - * session, you cannot currently do multiple ciphers/hashes in one - * session even though it would be possibel to code this driver to - * handle it. - */ - for (i = 0, c = cri; c && i < 2; i++) { - if (c->cri_alg == CRYPTO_MD5_HMAC || - c->cri_alg == CRYPTO_SHA1_HMAC || - c->cri_alg == CRYPTO_NULL_HMAC) { - if (macini) { - break; - } - macini = c; - } - if (c->cri_alg == CRYPTO_DES_CBC || - c->cri_alg == CRYPTO_3DES_CBC || - c->cri_alg == CRYPTO_AES_CBC || - c->cri_alg == CRYPTO_NULL_CBC) { - if (encini) { - break; - } - encini = c; - } - c = c->cri_next; - } - if (!macini && !encini) { - dprintk("%s,%d - EINVAL bad cipher/hash or combination\n", - __FILE__, __LINE__); - return EINVAL; - } - if (c) { - dprintk("%s,%d - EINVAL cannot handle chained cipher/hash combos\n", - __FILE__, __LINE__); - return EINVAL; - } - - /* - * So we have something we can do, lets setup the session - */ - - if (octo_sessions) { - for (i = 1; i < octo_sesnum; i++) - if (octo_sessions[i] == NULL) - break; - } else - i = 1; /* NB: to silence compiler warning */ - - if (octo_sessions == NULL || i == octo_sesnum) { - if (octo_sessions == NULL) { - i = 1; /* We leave octo_sessions[0] empty */ - octo_sesnum = CRYPTO_SW_SESSIONS; - } else - octo_sesnum *= 2; - - ocd = kmalloc(octo_sesnum * sizeof(struct octo_sess *), SLAB_ATOMIC); - if (ocd == NULL) { - /* Reset session number */ - if (octo_sesnum == CRYPTO_SW_SESSIONS) - octo_sesnum = 0; - else - octo_sesnum /= 2; - dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__); - return ENOBUFS; - } - memset(ocd, 0, octo_sesnum * sizeof(struct octo_sess *)); - - /* Copy existing sessions */ - if (octo_sessions) { - memcpy(ocd, octo_sessions, - (octo_sesnum / 2) * sizeof(struct octo_sess *)); - kfree(octo_sessions); - } - - octo_sessions = ocd; - } - - ocd = &octo_sessions[i]; - *sid = i; - - - *ocd = (struct octo_sess *) kmalloc(sizeof(struct octo_sess), SLAB_ATOMIC); - if (*ocd == NULL) { - octo_freesession(NULL, i); - dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__); - return ENOBUFS; - } - memset(*ocd, 0, sizeof(struct octo_sess)); - - if (encini && encini->cri_key) { - (*ocd)->octo_encklen = (encini->cri_klen + 7) / 8; - memcpy((*ocd)->octo_enckey, encini->cri_key, (*ocd)->octo_encklen); - } - - if (macini && macini->cri_key) { - (*ocd)->octo_macklen = (macini->cri_klen + 7) / 8; - memcpy((*ocd)->octo_mackey, macini->cri_key, (*ocd)->octo_macklen); - } - - (*ocd)->octo_mlen = 0; - if (encini && encini->cri_mlen) - (*ocd)->octo_mlen = encini->cri_mlen; - else if (macini && macini->cri_mlen) - (*ocd)->octo_mlen = macini->cri_mlen; - else - (*ocd)->octo_mlen = 12; - - /* - * point c at the enc if it exists, otherwise the mac - */ - c = encini ? encini : macini; - - switch (c->cri_alg) { - case CRYPTO_DES_CBC: - case CRYPTO_3DES_CBC: - (*ocd)->octo_ivsize = 8; - switch (macini ? macini->cri_alg : -1) { - case CRYPTO_MD5_HMAC: - (*ocd)->octo_encrypt = octo_des_cbc_md5_encrypt; - (*ocd)->octo_decrypt = octo_des_cbc_md5_decrypt; - octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner, - (*ocd)->octo_hmouter); - break; - case CRYPTO_SHA1_HMAC: - (*ocd)->octo_encrypt = octo_des_cbc_sha1_encrypt; - (*ocd)->octo_decrypt = octo_des_cbc_sha1_encrypt; - octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner, - (*ocd)->octo_hmouter); - break; - case -1: - (*ocd)->octo_encrypt = octo_des_cbc_encrypt; - (*ocd)->octo_decrypt = octo_des_cbc_decrypt; - break; - default: - octo_freesession(NULL, i); - dprintk("%s,%d: EINVALn", __FILE__, __LINE__); - return EINVAL; - } - break; - case CRYPTO_AES_CBC: - (*ocd)->octo_ivsize = 16; - switch (macini ? macini->cri_alg : -1) { - case CRYPTO_MD5_HMAC: - (*ocd)->octo_encrypt = octo_aes_cbc_md5_encrypt; - (*ocd)->octo_decrypt = octo_aes_cbc_md5_decrypt; - octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner, - (*ocd)->octo_hmouter); - break; - case CRYPTO_SHA1_HMAC: - (*ocd)->octo_encrypt = octo_aes_cbc_sha1_encrypt; - (*ocd)->octo_decrypt = octo_aes_cbc_sha1_decrypt; - octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner, - (*ocd)->octo_hmouter); - break; - case -1: - (*ocd)->octo_encrypt = octo_aes_cbc_encrypt; - (*ocd)->octo_decrypt = octo_aes_cbc_decrypt; - break; - default: - octo_freesession(NULL, i); - dprintk("%s,%d: EINVALn", __FILE__, __LINE__); - return EINVAL; - } - break; - case CRYPTO_MD5_HMAC: - (*ocd)->octo_encrypt = octo_null_md5_encrypt; - (*ocd)->octo_decrypt = octo_null_md5_encrypt; - octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner, - (*ocd)->octo_hmouter); - break; - case CRYPTO_SHA1_HMAC: - (*ocd)->octo_encrypt = octo_null_sha1_encrypt; - (*ocd)->octo_decrypt = octo_null_sha1_encrypt; - octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner, - (*ocd)->octo_hmouter); - break; - default: - octo_freesession(NULL, i); - dprintk("%s,%d: EINVALn", __FILE__, __LINE__); - return EINVAL; - } - - (*ocd)->octo_encalg = encini ? encini->cri_alg : -1; - (*ocd)->octo_macalg = macini ? macini->cri_alg : -1; - - return 0; -} - -/* - * Free a session. - */ -static int -octo_freesession(device_t dev, u_int64_t tid) -{ - u_int32_t sid = CRYPTO_SESID2LID(tid); - - dprintk("%s()\n", __FUNCTION__); - if (sid > octo_sesnum || octo_sessions == NULL || - octo_sessions[sid] == NULL) { - dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__); - return(EINVAL); - } - - /* Silently accept and return */ - if (sid == 0) - return(0); - - if (octo_sessions[sid]) - kfree(octo_sessions[sid]); - octo_sessions[sid] = NULL; - return 0; -} - -/* - * Process a request. - */ -static int -octo_process(device_t dev, struct cryptop *crp, int hint) -{ - struct cryptodesc *crd; - struct octo_sess *od; - u_int32_t lid; -#define SCATTERLIST_MAX 16 - struct scatterlist sg[SCATTERLIST_MAX]; - int sg_num, sg_len; - struct sk_buff *skb = NULL; - struct uio *uiop = NULL; - struct cryptodesc *enccrd = NULL, *maccrd = NULL; - unsigned char *ivp = NULL; - unsigned char iv_data[HASH_MAX_LEN]; - int auth_off = 0, auth_len = 0, crypt_off = 0, crypt_len = 0, icv_off = 0; - - dprintk("%s()\n", __FUNCTION__); - /* Sanity check */ - if (crp == NULL) { - dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__); - return EINVAL; - } - - crp->crp_etype = 0; - - if (crp->crp_desc == NULL || crp->crp_buf == NULL) { - dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__); - crp->crp_etype = EINVAL; - goto done; - } - - lid = crp->crp_sid & 0xffffffff; - if (lid >= octo_sesnum || lid == 0 || octo_sessions == NULL || - octo_sessions[lid] == NULL) { - crp->crp_etype = ENOENT; - dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__); - goto done; - } - od = octo_sessions[lid]; - - /* - * do some error checking outside of the loop for SKB and IOV processing - * this leaves us with valid skb or uiop pointers for later - */ - if (crp->crp_flags & CRYPTO_F_SKBUF) { - skb = (struct sk_buff *) crp->crp_buf; - if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) { - printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", __FILE__, __LINE__, - skb_shinfo(skb)->nr_frags); - goto done; - } - } else if (crp->crp_flags & CRYPTO_F_IOV) { - uiop = (struct uio *) crp->crp_buf; - if (uiop->uio_iovcnt > SCATTERLIST_MAX) { - printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", __FILE__, __LINE__, - uiop->uio_iovcnt); - goto done; - } - } - - /* point our enccrd and maccrd appropriately */ - crd = crp->crp_desc; - if (crd->crd_alg == od->octo_encalg) enccrd = crd; - if (crd->crd_alg == od->octo_macalg) maccrd = crd; - crd = crd->crd_next; - if (crd) { - if (crd->crd_alg == od->octo_encalg) enccrd = crd; - if (crd->crd_alg == od->octo_macalg) maccrd = crd; - crd = crd->crd_next; - } - if (crd) { - crp->crp_etype = EINVAL; - dprintk("%s,%d: ENOENT - descriptors do not match session\n", - __FILE__, __LINE__); - goto done; - } - - if (enccrd) { - if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) { - ivp = enccrd->crd_iv; - } else { - ivp = iv_data; - crypto_copydata(crp->crp_flags, crp->crp_buf, - enccrd->crd_inject, od->octo_ivsize, (caddr_t) ivp); - } - - if (maccrd) { - auth_off = maccrd->crd_skip; - auth_len = maccrd->crd_len; - icv_off = maccrd->crd_inject; - } - - crypt_off = enccrd->crd_skip; - crypt_len = enccrd->crd_len; - } else { /* if (maccrd) */ - auth_off = maccrd->crd_skip; - auth_len = maccrd->crd_len; - icv_off = maccrd->crd_inject; - } - - - /* - * setup the SG list to cover the buffer - */ - memset(sg, 0, sizeof(sg)); - if (crp->crp_flags & CRYPTO_F_SKBUF) { - int i, len; - - sg_num = 0; - sg_len = 0; - - len = skb_headlen(skb); - sg_set_page(&sg[sg_num], virt_to_page(skb->data), len, - offset_in_page(skb->data)); - sg_len += len; - sg_num++; - - for (i = 0; i < skb_shinfo(skb)->nr_frags && sg_num < SCATTERLIST_MAX; - i++) { - len = skb_shinfo(skb)->frags[i].size; - sg_set_page(&sg[sg_num], skb_shinfo(skb)->frags[i].page, - len, skb_shinfo(skb)->frags[i].page_offset); - sg_len += len; - sg_num++; - } - } else if (crp->crp_flags & CRYPTO_F_IOV) { - int len; - - sg_len = 0; - for (sg_num = 0; sg_len < crp->crp_ilen && - sg_num < uiop->uio_iovcnt && - sg_num < SCATTERLIST_MAX; sg_num++) { - len = uiop->uio_iov[sg_num].iov_len; - sg_set_page(&sg[sg_num], - virt_to_page(uiop->uio_iov[sg_num].iov_base), len, - offset_in_page(uiop->uio_iov[sg_num].iov_base)); - sg_len += len; - } - } else { - sg_len = crp->crp_ilen; - sg_set_page(&sg[0], virt_to_page(crp->crp_buf), sg_len, - offset_in_page(crp->crp_buf)); - sg_num = 1; - } - - - /* - * setup a new explicit key - */ - if (enccrd) { - if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) { - od->octo_encklen = (enccrd->crd_klen + 7) / 8; - memcpy(od->octo_enckey, enccrd->crd_key, od->octo_encklen); - } - } - if (maccrd) { - if (maccrd->crd_flags & CRD_F_KEY_EXPLICIT) { - od->octo_macklen = (maccrd->crd_klen + 7) / 8; - memcpy(od->octo_mackey, maccrd->crd_key, od->octo_macklen); - od->octo_mackey_set = 0; - } - if (!od->octo_mackey_set) { - octo_calc_hash(maccrd->crd_alg == CRYPTO_MD5_HMAC ? 0 : 1, - maccrd->crd_key, od->octo_hminner, od->octo_hmouter); - od->octo_mackey_set = 1; - } - } - - - if (!enccrd || (enccrd->crd_flags & CRD_F_ENCRYPT)) - (*od->octo_encrypt)(od, sg, sg_len, - auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp); - else - (*od->octo_decrypt)(od, sg, sg_len, - auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp); - -done: - crypto_done(crp); - return 0; -} - -static int -cryptocteon_init(void) -{ - dprintk("%s(%p)\n", __FUNCTION__, cryptocteon_init); - - softc_device_init(&octo_softc, "cryptocteon", 0, octo_methods); - - octo_id = crypto_get_driverid(softc_get_device(&octo_softc), - CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SYNC); - if (octo_id < 0) { - printk("Cryptocteon device cannot initialize!"); - return -ENODEV; - } - - crypto_register(octo_id, CRYPTO_MD5_HMAC, 0,0); - crypto_register(octo_id, CRYPTO_SHA1_HMAC, 0,0); - //crypto_register(octo_id, CRYPTO_MD5, 0,0); - //crypto_register(octo_id, CRYPTO_SHA1, 0,0); - crypto_register(octo_id, CRYPTO_DES_CBC, 0,0); - crypto_register(octo_id, CRYPTO_3DES_CBC, 0,0); - crypto_register(octo_id, CRYPTO_AES_CBC, 0,0); - - return(0); -} - -static void -cryptocteon_exit(void) -{ - dprintk("%s()\n", __FUNCTION__); - crypto_unregister_all(octo_id); - octo_id = -1; -} - -module_init(cryptocteon_init); -module_exit(cryptocteon_exit); - -MODULE_LICENSE("BSD"); -MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>"); -MODULE_DESCRIPTION("Cryptocteon (OCF module for Cavium OCTEON crypto)"); |