The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/mips/cavium/cryptocteon/cavium_crypto.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * vim:sw=4 ts=8
    3  */
    4 /*
    5  * Copyright (c) 2009 David McCullough <david.mccullough@securecomputing.com>
    6  *
    7  * Copyright (c) 2003-2007 Cavium Networks (support@cavium.com). All rights
    8  * reserved.
    9  * 
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions are met:
   12  * 1. Redistributions of source code must retain the above copyright notice,
   13  * this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright notice,
   15  * this list of conditions and the following disclaimer in the documentation
   16  * and/or other materials provided with the distribution.
   17  * 3. All advertising materials mentioning features or use of this software
   18  * must display the following acknowledgement:
   19  * This product includes software developed by Cavium Networks
   20  * 4. Cavium Networks' name may not be used to endorse or promote products
   21  * derived from this software without specific prior written permission.
   22  * 
   23  * This Software, including technical data, may be subject to U.S. export
   24  * control laws, including the U.S. Export Administration Act and its
   25  * associated regulations, and may be subject to export or import regulations
   26  * in other countries. You warrant that You will comply strictly in all
   27  * respects with all such regulations and acknowledge that you have the
   28  * responsibility to obtain licenses to export, re-export or import the
   29  * Software.
   30  * 
   31  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" AND
   32  * WITH ALL FAULTS AND CAVIUM MAKES NO PROMISES, REPRESENTATIONS OR WARRANTIES,
   33  * EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO THE
   34  * SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
   35  * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
   36  * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
   37  * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
   38  * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
   39  * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
   40  * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
   41 */
   42 /****************************************************************************/
   43 
   44 #include <sys/cdefs.h>
   45 __FBSDID("$FreeBSD$");
   46 
   47 #include <sys/param.h>
   48 #include <sys/systm.h>
   49 #include <sys/kernel.h>
   50 #include <sys/module.h>
   51 #include <sys/malloc.h>
   52 #include <sys/uio.h>
   53 
   54 #include <opencrypto/cryptodev.h>
   55 
   56 #include <contrib/octeon-sdk/cvmx.h>
   57 
   58 #include <mips/cavium/cryptocteon/cryptocteonvar.h>
   59 
   60 /****************************************************************************/
   61 
   62 #define IOV_INIT(iov, ptr, idx, len)                                    \
   63         do {                                                            \
   64             (idx) = 0;                                                  \
   65             (ptr) = (iov)[(idx)].iov_base;                              \
   66             (len) = (iov)[(idx)].iov_len;                               \
   67         } while (0)
   68 
   69 /*
   70  * XXX
   71  * It would be better if this were an IOV_READ/IOV_WRITE macro instead so
   72  * that we could detect overflow before it happens rather than right after,
   73  * which is especially bad since there is usually no IOV_CONSUME after the
   74  * final read or write.
   75  */
   76 #define IOV_CONSUME(iov, ptr, idx, len)                                 \
   77         do {                                                            \
   78             if ((len) > sizeof *(ptr)) {                                \
   79                 (len) -= sizeof *(ptr);                                 \
   80                 (ptr)++;                                                \
   81             } else {                                                    \
   82                 if ((len) != sizeof *(ptr))                             \
   83                         panic("%s: went past end of iovec.", __func__); \
   84                 (idx)++;                                                \
   85                 (ptr) = (iov)[(idx)].iov_base;                          \
   86                 (len) = (iov)[(idx)].iov_len;                           \
   87             }                                                           \
   88         } while (0)
   89 
   90 static inline unsigned long octeon_crypto_enable(void)
   91 {
   92     register_t s;
   93     
   94     s = intr_disable();
   95     mips_wr_status(mips_rd_status() | MIPS_SR_COP_2_BIT);
   96 
   97     return (s);
   98 }
   99 
  100 static inline void octeon_crypto_disable(register_t s)
  101 {
  102     mips_wr_status(mips_rd_status() & ~MIPS_SR_COP_2_BIT);
  103     intr_restore(s);
  104 }
  105 
  106 #define ESP_HEADER_LENGTH     8
  107 #define DES_CBC_IV_LENGTH     8
  108 #define AES_CBC_IV_LENGTH     16
  109 #define ESP_HMAC_LEN          12
  110 
  111 #define ESP_HEADER_LENGTH 8
  112 #define DES_CBC_IV_LENGTH 8
  113 
  114 /****************************************************************************/
  115 
  116 #define CVM_LOAD_SHA_UNIT(dat, next)  { \
  117    if (next == 0) {                     \
  118       next = 1;                         \
  119       CVMX_MT_HSH_DAT (dat, 0);         \
  120    } else if (next == 1) {              \
  121       next = 2;                         \
  122       CVMX_MT_HSH_DAT (dat, 1);         \
  123    } else if (next == 2) {              \
  124       next = 3;                    \
  125       CVMX_MT_HSH_DAT (dat, 2);         \
  126    } else if (next == 3) {              \
  127       next = 4;                         \
  128       CVMX_MT_HSH_DAT (dat, 3);         \
  129    } else if (next == 4) {              \
  130       next = 5;                           \
  131       CVMX_MT_HSH_DAT (dat, 4);         \
  132    } else if (next == 5) {              \
  133       next = 6;                         \
  134       CVMX_MT_HSH_DAT (dat, 5);         \
  135    } else if (next == 6) {              \
  136       next = 7;                         \
  137       CVMX_MT_HSH_DAT (dat, 6);         \
  138    } else {                             \
  139      CVMX_MT_HSH_STARTSHA (dat);        \
  140      next = 0;                          \
  141    }                                    \
  142 }
  143 
  144 #define CVM_LOAD2_SHA_UNIT(dat1, dat2, next)  { \
  145    if (next == 0) {                      \
  146       CVMX_MT_HSH_DAT (dat1, 0);         \
  147       CVMX_MT_HSH_DAT (dat2, 1);         \
  148       next = 2;                          \
  149    } else if (next == 1) {               \
  150       CVMX_MT_HSH_DAT (dat1, 1);         \
  151       CVMX_MT_HSH_DAT (dat2, 2);         \
  152       next = 3;                          \
  153    } else if (next == 2) {               \
  154       CVMX_MT_HSH_DAT (dat1, 2);         \
  155       CVMX_MT_HSH_DAT (dat2, 3);         \
  156       next = 4;                          \
  157    } else if (next == 3) {               \
  158       CVMX_MT_HSH_DAT (dat1, 3);         \
  159       CVMX_MT_HSH_DAT (dat2, 4);         \
  160       next = 5;                          \
  161    } else if (next == 4) {               \
  162       CVMX_MT_HSH_DAT (dat1, 4);         \
  163       CVMX_MT_HSH_DAT (dat2, 5);         \
  164       next = 6;                          \
  165    } else if (next == 5) {               \
  166       CVMX_MT_HSH_DAT (dat1, 5);         \
  167       CVMX_MT_HSH_DAT (dat2, 6);         \
  168       next = 7;                          \
  169    } else if (next == 6) {               \
  170       CVMX_MT_HSH_DAT (dat1, 6);         \
  171       CVMX_MT_HSH_STARTSHA (dat2);       \
  172       next = 0;                          \
  173    } else {                              \
  174      CVMX_MT_HSH_STARTSHA (dat1);        \
  175      CVMX_MT_HSH_DAT (dat2, 0);          \
  176      next = 1;                           \
  177    }                                     \
  178 }
  179 
  180 /****************************************************************************/
  181 
  182 #define CVM_LOAD_MD5_UNIT(dat, next)  { \
  183    if (next == 0) {                     \
  184       next = 1;                         \
  185       CVMX_MT_HSH_DAT (dat, 0);         \
  186    } else if (next == 1) {              \
  187       next = 2;                         \
  188       CVMX_MT_HSH_DAT (dat, 1);         \
  189    } else if (next == 2) {              \
  190       next = 3;                    \
  191       CVMX_MT_HSH_DAT (dat, 2);         \
  192    } else if (next == 3) {              \
  193       next = 4;                         \
  194       CVMX_MT_HSH_DAT (dat, 3);         \
  195    } else if (next == 4) {              \
  196       next = 5;                           \
  197       CVMX_MT_HSH_DAT (dat, 4);         \
  198    } else if (next == 5) {              \
  199       next = 6;                         \
  200       CVMX_MT_HSH_DAT (dat, 5);         \
  201    } else if (next == 6) {              \
  202       next = 7;                         \
  203       CVMX_MT_HSH_DAT (dat, 6);         \
  204    } else {                             \
  205      CVMX_MT_HSH_STARTMD5 (dat);        \
  206      next = 0;                          \
  207    }                                    \
  208 }
  209 
  210 #define CVM_LOAD2_MD5_UNIT(dat1, dat2, next)  { \
  211    if (next == 0) {                      \
  212       CVMX_MT_HSH_DAT (dat1, 0);         \
  213       CVMX_MT_HSH_DAT (dat2, 1);         \
  214       next = 2;                          \
  215    } else if (next == 1) {               \
  216       CVMX_MT_HSH_DAT (dat1, 1);         \
  217       CVMX_MT_HSH_DAT (dat2, 2);         \
  218       next = 3;                          \
  219    } else if (next == 2) {               \
  220       CVMX_MT_HSH_DAT (dat1, 2);         \
  221       CVMX_MT_HSH_DAT (dat2, 3);         \
  222       next = 4;                          \
  223    } else if (next == 3) {               \
  224       CVMX_MT_HSH_DAT (dat1, 3);         \
  225       CVMX_MT_HSH_DAT (dat2, 4);         \
  226       next = 5;                          \
  227    } else if (next == 4) {               \
  228       CVMX_MT_HSH_DAT (dat1, 4);         \
  229       CVMX_MT_HSH_DAT (dat2, 5);         \
  230       next = 6;                          \
  231    } else if (next == 5) {               \
  232       CVMX_MT_HSH_DAT (dat1, 5);         \
  233       CVMX_MT_HSH_DAT (dat2, 6);         \
  234       next = 7;                          \
  235    } else if (next == 6) {               \
  236       CVMX_MT_HSH_DAT (dat1, 6);         \
  237       CVMX_MT_HSH_STARTMD5 (dat2);       \
  238       next = 0;                          \
  239    } else {                              \
  240      CVMX_MT_HSH_STARTMD5 (dat1);        \
  241      CVMX_MT_HSH_DAT (dat2, 0);          \
  242      next = 1;                           \
  243    }                                     \
  244 }
  245 
  246 /****************************************************************************/
  247 
  248 void
  249 octo_calc_hash(uint8_t auth, unsigned char *key, uint64_t *inner, uint64_t *outer)
  250 {
  251     uint8_t hash_key[64];
  252     uint64_t *key1;
  253     register uint64_t xor1 = 0x3636363636363636ULL;
  254     register uint64_t xor2 = 0x5c5c5c5c5c5c5c5cULL;
  255     register_t s;
  256 
  257     dprintf("%s()\n", __func__);
  258 
  259     memset(hash_key, 0, sizeof(hash_key));
  260     memcpy(hash_key, (uint8_t *) key, (auth ? 20 : 16));
  261     key1 = (uint64_t *) hash_key;
  262     s = octeon_crypto_enable();
  263     if (auth) {
  264        CVMX_MT_HSH_IV(0x67452301EFCDAB89ULL, 0);
  265        CVMX_MT_HSH_IV(0x98BADCFE10325476ULL, 1);
  266        CVMX_MT_HSH_IV(0xC3D2E1F000000000ULL, 2);
  267     } else {
  268        CVMX_MT_HSH_IV(0x0123456789ABCDEFULL, 0);
  269        CVMX_MT_HSH_IV(0xFEDCBA9876543210ULL, 1);
  270     }
  271 
  272     CVMX_MT_HSH_DAT((*key1 ^ xor1), 0);
  273     key1++;
  274     CVMX_MT_HSH_DAT((*key1 ^ xor1), 1);
  275     key1++;
  276     CVMX_MT_HSH_DAT((*key1 ^ xor1), 2);
  277     key1++;
  278     CVMX_MT_HSH_DAT((*key1 ^ xor1), 3);
  279     key1++;
  280     CVMX_MT_HSH_DAT((*key1 ^ xor1), 4);
  281     key1++;
  282     CVMX_MT_HSH_DAT((*key1 ^ xor1), 5);
  283     key1++;
  284     CVMX_MT_HSH_DAT((*key1 ^ xor1), 6);
  285     key1++;
  286     if (auth)
  287                 CVMX_MT_HSH_STARTSHA((*key1 ^ xor1));
  288     else
  289                 CVMX_MT_HSH_STARTMD5((*key1 ^ xor1));
  290 
  291     CVMX_MF_HSH_IV(inner[0], 0);
  292     CVMX_MF_HSH_IV(inner[1], 1);
  293     if (auth) {
  294                 inner[2] = 0;
  295                 CVMX_MF_HSH_IV(((uint64_t *) inner)[2], 2);
  296     }
  297 
  298     memset(hash_key, 0, sizeof(hash_key));
  299     memcpy(hash_key, (uint8_t *) key, (auth ? 20 : 16));
  300     key1 = (uint64_t *) hash_key;
  301     if (auth) {
  302       CVMX_MT_HSH_IV(0x67452301EFCDAB89ULL, 0);
  303       CVMX_MT_HSH_IV(0x98BADCFE10325476ULL, 1);
  304       CVMX_MT_HSH_IV(0xC3D2E1F000000000ULL, 2);
  305     } else {
  306       CVMX_MT_HSH_IV(0x0123456789ABCDEFULL, 0);
  307       CVMX_MT_HSH_IV(0xFEDCBA9876543210ULL, 1);
  308     }
  309 
  310     CVMX_MT_HSH_DAT((*key1 ^ xor2), 0);
  311     key1++;
  312     CVMX_MT_HSH_DAT((*key1 ^ xor2), 1);
  313     key1++;
  314     CVMX_MT_HSH_DAT((*key1 ^ xor2), 2);
  315     key1++;
  316     CVMX_MT_HSH_DAT((*key1 ^ xor2), 3);
  317     key1++;
  318     CVMX_MT_HSH_DAT((*key1 ^ xor2), 4);
  319     key1++;
  320     CVMX_MT_HSH_DAT((*key1 ^ xor2), 5);
  321     key1++;
  322     CVMX_MT_HSH_DAT((*key1 ^ xor2), 6);
  323     key1++;
  324     if (auth)
  325        CVMX_MT_HSH_STARTSHA((*key1 ^ xor2));
  326     else 
  327        CVMX_MT_HSH_STARTMD5((*key1 ^ xor2));
  328 
  329     CVMX_MF_HSH_IV(outer[0], 0);
  330     CVMX_MF_HSH_IV(outer[1], 1);
  331     if (auth) {
  332       outer[2] = 0;
  333       CVMX_MF_HSH_IV(outer[2], 2);
  334     }
  335     octeon_crypto_disable(s);
  336     return;
  337 }
  338 
  339 /****************************************************************************/
  340 /* DES functions */
  341 
  342 int
  343 octo_des_cbc_encrypt(
  344     struct octo_sess *od,
  345     struct iovec *iov, size_t iovcnt, size_t iovlen,
  346     int auth_off, int auth_len,
  347     int crypt_off, int crypt_len,
  348     int icv_off, uint8_t *ivp)
  349 {
  350     uint64_t *data;
  351     int data_i, data_l;
  352     register_t s;
  353 
  354     dprintf("%s()\n", __func__);
  355 
  356     if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL ||
  357             (crypt_off & 0x7) || (crypt_off + crypt_len > iovlen))) {
  358         dprintf("%s: Bad parameters od=%p iov=%p iovlen=%d "
  359                 "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  360                 "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen,
  361                 auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  362         return -EINVAL;
  363     }
  364 
  365     IOV_INIT(iov, data, data_i, data_l);
  366 
  367     CVMX_PREFETCH0(ivp);
  368     CVMX_PREFETCH0(od->octo_enckey);
  369 
  370     s = octeon_crypto_enable();
  371 
  372     /* load 3DES Key */
  373     CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  374     if (od->octo_encklen == 24) {
  375         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  376         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  377     } else if (od->octo_encklen == 8) {
  378         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  379         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  380     } else {
  381         octeon_crypto_disable(s);
  382         dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen);
  383         return -EINVAL;
  384     }
  385 
  386     CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  387 
  388     while (crypt_off > 0) {
  389         IOV_CONSUME(iov, data, data_i, data_l);
  390         crypt_off -= 8;
  391     }
  392 
  393     while (crypt_len > 0) {
  394         CVMX_MT_3DES_ENC_CBC(*data);
  395         CVMX_MF_3DES_RESULT(*data);
  396         IOV_CONSUME(iov, data, data_i, data_l);
  397         crypt_len -= 8;
  398     }
  399 
  400     octeon_crypto_disable(s);
  401     return 0;
  402 }
  403 
  404 
  405 int
  406 octo_des_cbc_decrypt(
  407     struct octo_sess *od,
  408     struct iovec *iov, size_t iovcnt, size_t iovlen,
  409     int auth_off, int auth_len,
  410     int crypt_off, int crypt_len,
  411     int icv_off, uint8_t *ivp)
  412 {
  413     uint64_t *data;
  414     int data_i, data_l;
  415     register_t s;
  416 
  417     dprintf("%s()\n", __func__);
  418 
  419     if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL ||
  420             (crypt_off & 0x7) || (crypt_off + crypt_len > iovlen))) {
  421         dprintf("%s: Bad parameters od=%p iov=%p iovlen=%d "
  422                 "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  423                 "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen,
  424                 auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  425         return -EINVAL;
  426     }
  427 
  428     IOV_INIT(iov, data, data_i, data_l);
  429 
  430     CVMX_PREFETCH0(ivp);
  431     CVMX_PREFETCH0(od->octo_enckey);
  432 
  433     s = octeon_crypto_enable();
  434 
  435     /* load 3DES Key */
  436     CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  437     if (od->octo_encklen == 24) {
  438         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  439         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  440     } else if (od->octo_encklen == 8) {
  441         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  442         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  443     } else {
  444         octeon_crypto_disable(s);
  445         dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen);
  446         return -EINVAL;
  447     }
  448 
  449     CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  450 
  451     while (crypt_off > 0) {
  452         IOV_CONSUME(iov, data, data_i, data_l);
  453         crypt_off -= 8;
  454     }
  455 
  456     while (crypt_len > 0) {
  457         CVMX_MT_3DES_DEC_CBC(*data);
  458         CVMX_MF_3DES_RESULT(*data);
  459         IOV_CONSUME(iov, data, data_i, data_l);
  460         crypt_len -= 8;
  461     }
  462 
  463     octeon_crypto_disable(s);
  464     return 0;
  465 }
  466 
  467 /****************************************************************************/
  468 /* AES functions */
  469 
  470 int
  471 octo_aes_cbc_encrypt(
  472     struct octo_sess *od,
  473     struct iovec *iov, size_t iovcnt, size_t iovlen,
  474     int auth_off, int auth_len,
  475     int crypt_off, int crypt_len,
  476     int icv_off, uint8_t *ivp)
  477 {
  478     uint64_t *data, *pdata;
  479     int data_i, data_l;
  480     register_t s;
  481 
  482     dprintf("%s()\n", __func__);
  483 
  484     if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL ||
  485             (crypt_off & 0x7) || (crypt_off + crypt_len > iovlen))) {
  486         dprintf("%s: Bad parameters od=%p iov=%p iovlen=%d "
  487                 "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  488                 "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen,
  489                 auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  490         return -EINVAL;
  491     }
  492 
  493     IOV_INIT(iov, data, data_i, data_l);
  494 
  495     CVMX_PREFETCH0(ivp);
  496     CVMX_PREFETCH0(od->octo_enckey);
  497 
  498     s = octeon_crypto_enable();
  499 
  500     /* load AES Key */
  501     CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  502     CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  503 
  504     if (od->octo_encklen == 16) {
  505         CVMX_MT_AES_KEY(0x0, 2);
  506         CVMX_MT_AES_KEY(0x0, 3);
  507     } else if (od->octo_encklen == 24) {
  508         CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  509         CVMX_MT_AES_KEY(0x0, 3);
  510     } else if (od->octo_encklen == 32) {
  511         CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  512         CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
  513     } else {
  514         octeon_crypto_disable(s);
  515         dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen);
  516         return -EINVAL;
  517     }
  518     CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
  519 
  520     CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
  521     CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
  522 
  523     while (crypt_off > 0) {
  524         IOV_CONSUME(iov, data, data_i, data_l);
  525         crypt_off -= 8;
  526     }
  527 
  528     while (crypt_len > 0) {
  529         pdata = data;
  530         CVMX_MT_AES_ENC_CBC0(*data);
  531         IOV_CONSUME(iov, data, data_i, data_l);
  532         CVMX_MT_AES_ENC_CBC1(*data);
  533         CVMX_MF_AES_RESULT(*pdata, 0);
  534         CVMX_MF_AES_RESULT(*data, 1);
  535         IOV_CONSUME(iov, data, data_i, data_l);
  536         crypt_len -= 16;
  537     }
  538 
  539     octeon_crypto_disable(s);
  540     return 0;
  541 }
  542 
  543 
  544 int
  545 octo_aes_cbc_decrypt(
  546     struct octo_sess *od,
  547     struct iovec *iov, size_t iovcnt, size_t iovlen,
  548     int auth_off, int auth_len,
  549     int crypt_off, int crypt_len,
  550     int icv_off, uint8_t *ivp)
  551 {
  552     uint64_t *data, *pdata;
  553     int data_i, data_l;
  554     register_t s;
  555 
  556     dprintf("%s()\n", __func__);
  557 
  558     if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL ||
  559             (crypt_off & 0x7) || (crypt_off + crypt_len > iovlen))) {
  560         dprintf("%s: Bad parameters od=%p iov=%p iovlen=%d "
  561                 "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  562                 "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen,
  563                 auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  564         return -EINVAL;
  565     }
  566 
  567     IOV_INIT(iov, data, data_i, data_l);
  568 
  569     CVMX_PREFETCH0(ivp);
  570     CVMX_PREFETCH0(od->octo_enckey);
  571 
  572     s = octeon_crypto_enable();
  573 
  574     /* load AES Key */
  575     CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  576     CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  577 
  578     if (od->octo_encklen == 16) {
  579         CVMX_MT_AES_KEY(0x0, 2);
  580         CVMX_MT_AES_KEY(0x0, 3);
  581     } else if (od->octo_encklen == 24) {
  582         CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  583         CVMX_MT_AES_KEY(0x0, 3);
  584     } else if (od->octo_encklen == 32) {
  585         CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  586         CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
  587     } else {
  588         octeon_crypto_disable(s);
  589         dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen);
  590         return -EINVAL;
  591     }
  592     CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
  593 
  594     CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
  595     CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
  596 
  597     while (crypt_off > 0) {
  598         IOV_CONSUME(iov, data, data_i, data_l);
  599         crypt_off -= 8;
  600     }
  601 
  602     while (crypt_len > 0) {
  603         pdata = data;
  604         CVMX_MT_AES_DEC_CBC0(*data);
  605         IOV_CONSUME(iov, data, data_i, data_l);
  606         CVMX_MT_AES_DEC_CBC1(*data);
  607         CVMX_MF_AES_RESULT(*pdata, 0);
  608         CVMX_MF_AES_RESULT(*data, 1);
  609         IOV_CONSUME(iov, data, data_i, data_l);
  610         crypt_len -= 16;
  611     }
  612 
  613     octeon_crypto_disable(s);
  614     return 0;
  615 }
  616 
  617 /****************************************************************************/
  618 /* MD5 */
  619 
  620 int
  621 octo_null_md5_encrypt(
  622     struct octo_sess *od,
  623     struct iovec *iov, size_t iovcnt, size_t iovlen,
  624     int auth_off, int auth_len,
  625     int crypt_off, int crypt_len,
  626     int icv_off, uint8_t *ivp)
  627 {
  628     register int next = 0;
  629     uint64_t *data;
  630     uint64_t tmp1, tmp2;
  631     int data_i, data_l, alen = auth_len;
  632     register_t s;
  633 
  634     dprintf("%s()\n", __func__);
  635 
  636     if (__predict_false(od == NULL || iov==NULL || iovlen==0 ||
  637             (auth_off & 0x7) || (auth_off + auth_len > iovlen))) {
  638         dprintf("%s: Bad parameters od=%p iov=%p iovlen=%d "
  639                 "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  640                 "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen,
  641                 auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  642         return -EINVAL;
  643     }
  644 
  645     IOV_INIT(iov, data, data_i, data_l);
  646 
  647     s = octeon_crypto_enable();
  648 
  649     /* Load MD5 IV */
  650     CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  651     CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  652 
  653     while (auth_off > 0) {
  654         IOV_CONSUME(iov, data, data_i, data_l);
  655         auth_off -= 8;
  656     }
  657 
  658     while (auth_len > 0) {
  659         CVM_LOAD_MD5_UNIT(*data, next);
  660         auth_len -= 8;
  661         IOV_CONSUME(iov, data, data_i, data_l);
  662     }
  663 
  664     /* finish the hash */
  665     CVMX_PREFETCH0(od->octo_hmouter);
  666 #if 0
  667     if (__predict_false(inplen)) {
  668         uint64_t tmp = 0;
  669         uint8_t *p = (uint8_t *) & tmp;
  670         p[inplen] = 0x80;
  671         do {
  672             inplen--;
  673             p[inplen] = ((uint8_t *) data)[inplen];
  674         } while (inplen);
  675         CVM_LOAD_MD5_UNIT(tmp, next);
  676     } else {
  677         CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  678     }
  679 #else
  680     CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  681 #endif
  682 
  683     /* Finish Inner hash */
  684     while (next != 7) {
  685         CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
  686     }
  687     CVMX_ES64(tmp1, ((alen + 64) << 3));
  688     CVM_LOAD_MD5_UNIT(tmp1, next);
  689 
  690     /* Get the inner hash of HMAC */
  691     CVMX_MF_HSH_IV(tmp1, 0);
  692     CVMX_MF_HSH_IV(tmp2, 1);
  693 
  694     /* Initialize hash unit */
  695     CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  696     CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  697 
  698     CVMX_MT_HSH_DAT(tmp1, 0);
  699     CVMX_MT_HSH_DAT(tmp2, 1);
  700     CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
  701     CVMX_MT_HSH_DATZ(3);
  702     CVMX_MT_HSH_DATZ(4);
  703     CVMX_MT_HSH_DATZ(5);
  704     CVMX_MT_HSH_DATZ(6);
  705     CVMX_ES64(tmp1, ((64 + 16) << 3));
  706     CVMX_MT_HSH_STARTMD5(tmp1);
  707 
  708     /* save the HMAC */
  709     IOV_INIT(iov, data, data_i, data_l);
  710     while (icv_off > 0) {
  711         IOV_CONSUME(iov, data, data_i, data_l);
  712         icv_off -= 8;
  713     }
  714     CVMX_MF_HSH_IV(*data, 0);
  715     IOV_CONSUME(iov, data, data_i, data_l);
  716     CVMX_MF_HSH_IV(tmp1, 1);
  717     *(uint32_t *)data = (uint32_t) (tmp1 >> 32);
  718 
  719     octeon_crypto_disable(s);
  720     return 0;
  721 }
  722 
  723 /****************************************************************************/
  724 /* SHA1 */
  725 
  726 int
  727 octo_null_sha1_encrypt(
  728     struct octo_sess *od,
  729     struct iovec *iov, size_t iovcnt, size_t iovlen,
  730     int auth_off, int auth_len,
  731     int crypt_off, int crypt_len,
  732     int icv_off, uint8_t *ivp)
  733 {
  734     register int next = 0;
  735     uint64_t *data;
  736     uint64_t tmp1, tmp2, tmp3;
  737     int data_i, data_l, alen = auth_len;
  738     register_t s;
  739 
  740     dprintf("%s()\n", __func__);
  741 
  742     if (__predict_false(od == NULL || iov==NULL || iovlen==0 ||
  743             (auth_off & 0x7) || (auth_off + auth_len > iovlen))) {
  744         dprintf("%s: Bad parameters od=%p iov=%p iovlen=%d "
  745                 "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  746                 "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen,
  747                 auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  748         return -EINVAL;
  749     }
  750 
  751     IOV_INIT(iov, data, data_i, data_l);
  752 
  753     s = octeon_crypto_enable();
  754 
  755     /* Load SHA1 IV */
  756     CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  757     CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  758     CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
  759 
  760     while (auth_off > 0) {
  761         IOV_CONSUME(iov, data, data_i, data_l);
  762         auth_off -= 8;
  763     }
  764 
  765     while (auth_len > 0) {
  766         CVM_LOAD_SHA_UNIT(*data, next);
  767         auth_len -= 8;
  768         IOV_CONSUME(iov, data, data_i, data_l);
  769     }
  770 
  771     /* finish the hash */
  772     CVMX_PREFETCH0(od->octo_hmouter);
  773 #if 0
  774     if (__predict_false(inplen)) {
  775         uint64_t tmp = 0;
  776         uint8_t *p = (uint8_t *) & tmp;
  777         p[inplen] = 0x80;
  778         do {
  779             inplen--;
  780             p[inplen] = ((uint8_t *) data)[inplen];
  781         } while (inplen);
  782         CVM_LOAD_MD5_UNIT(tmp, next);
  783     } else {
  784         CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  785     }
  786 #else
  787     CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  788 #endif
  789 
  790     /* Finish Inner hash */
  791     while (next != 7) {
  792         CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
  793     }
  794         CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
  795 
  796     /* Get the inner hash of HMAC */
  797     CVMX_MF_HSH_IV(tmp1, 0);
  798     CVMX_MF_HSH_IV(tmp2, 1);
  799     tmp3 = 0;
  800     CVMX_MF_HSH_IV(tmp3, 2);
  801 
  802     /* Initialize hash unit */
  803     CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  804     CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  805     CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
  806 
  807     CVMX_MT_HSH_DAT(tmp1, 0);
  808     CVMX_MT_HSH_DAT(tmp2, 1);
  809     tmp3 |= 0x0000000080000000;
  810     CVMX_MT_HSH_DAT(tmp3, 2);
  811     CVMX_MT_HSH_DATZ(3);
  812     CVMX_MT_HSH_DATZ(4);
  813     CVMX_MT_HSH_DATZ(5);
  814     CVMX_MT_HSH_DATZ(6);
  815     CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
  816 
  817     /* save the HMAC */
  818     IOV_INIT(iov, data, data_i, data_l);
  819     while (icv_off > 0) {
  820         IOV_CONSUME(iov, data, data_i, data_l);
  821         icv_off -= 8;
  822     }
  823     CVMX_MF_HSH_IV(*data, 0);
  824     IOV_CONSUME(iov, data, data_i, data_l);
  825     CVMX_MF_HSH_IV(tmp1, 1);
  826     *(uint32_t *)data = (uint32_t) (tmp1 >> 32);
  827 
  828     octeon_crypto_disable(s);
  829     return 0;
  830 }
  831 
  832 /****************************************************************************/
  833 /* DES MD5 */
  834 
  835 int
  836 octo_des_cbc_md5_encrypt(
  837     struct octo_sess *od,
  838     struct iovec *iov, size_t iovcnt, size_t iovlen,
  839     int auth_off, int auth_len,
  840     int crypt_off, int crypt_len,
  841     int icv_off, uint8_t *ivp)
  842 {
  843     register int next = 0;
  844     union {
  845         uint32_t data32[2];
  846         uint64_t data64[1];
  847     } mydata;
  848     uint64_t *data = &mydata.data64[0];
  849     uint32_t *data32;
  850     uint64_t tmp1, tmp2;
  851     int data_i, data_l, alen = auth_len;
  852     register_t s;
  853 
  854     dprintf("%s()\n", __func__);
  855 
  856     if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL ||
  857             (crypt_off & 0x3) || (crypt_off + crypt_len > iovlen) ||
  858             (crypt_len  & 0x7) ||
  859             (auth_len  & 0x7) ||
  860             (auth_off & 0x3) || (auth_off + auth_len > iovlen))) {
  861         dprintf("%s: Bad parameters od=%p iov=%p iovlen=%d "
  862                 "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  863                 "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen,
  864                 auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  865         return -EINVAL;
  866     }
  867 
  868     IOV_INIT(iov, data32, data_i, data_l);
  869 
  870     CVMX_PREFETCH0(ivp);
  871     CVMX_PREFETCH0(od->octo_enckey);
  872 
  873     s = octeon_crypto_enable();
  874 
  875     /* load 3DES Key */
  876     CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  877     if (od->octo_encklen == 24) {
  878         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  879         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  880     } else if (od->octo_encklen == 8) {
  881         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  882         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  883     } else {
  884         octeon_crypto_disable(s);
  885         dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen);
  886         return -EINVAL;
  887     }
  888 
  889     CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  890 
  891     /* Load MD5 IV */
  892     CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  893     CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  894 
  895     while (crypt_off > 0 && auth_off > 0) {
  896         IOV_CONSUME(iov, data32, data_i, data_l);
  897         crypt_off -= 4;
  898         auth_off -= 4;
  899     }
  900 
  901     while (crypt_len > 0 || auth_len > 0) {
  902         uint32_t *first = data32;
  903         mydata.data32[0] = *first;
  904         IOV_CONSUME(iov, data32, data_i, data_l);
  905         mydata.data32[1] = *data32;
  906         if (crypt_off <= 0) {
  907             if (crypt_len > 0) {
  908                 CVMX_MT_3DES_ENC_CBC(*data);
  909                 CVMX_MF_3DES_RESULT(*data);
  910                 crypt_len -= 8;
  911             }
  912         } else
  913             crypt_off -= 8;
  914         if (auth_off <= 0) {
  915             if (auth_len > 0) {
  916                 CVM_LOAD_MD5_UNIT(*data, next);
  917                 auth_len -= 8;
  918             }
  919         } else
  920             auth_off -= 8;
  921         *first = mydata.data32[0];
  922         *data32 = mydata.data32[1];
  923         IOV_CONSUME(iov, data32, data_i, data_l);
  924     }
  925 
  926     /* finish the hash */
  927     CVMX_PREFETCH0(od->octo_hmouter);
  928 #if 0
  929     if (__predict_false(inplen)) {
  930         uint64_t tmp = 0;
  931         uint8_t *p = (uint8_t *) & tmp;
  932         p[inplen] = 0x80;
  933         do {
  934             inplen--;
  935             p[inplen] = ((uint8_t *) data)[inplen];
  936         } while (inplen);
  937         CVM_LOAD_MD5_UNIT(tmp, next);
  938     } else {
  939         CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  940     }
  941 #else
  942     CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  943 #endif
  944 
  945     /* Finish Inner hash */
  946     while (next != 7) {
  947         CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
  948     }
  949     CVMX_ES64(tmp1, ((alen + 64) << 3));
  950     CVM_LOAD_MD5_UNIT(tmp1, next);
  951 
  952     /* Get the inner hash of HMAC */
  953     CVMX_MF_HSH_IV(tmp1, 0);
  954     CVMX_MF_HSH_IV(tmp2, 1);
  955 
  956     /* Initialize hash unit */
  957     CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  958     CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  959 
  960     CVMX_MT_HSH_DAT(tmp1, 0);
  961     CVMX_MT_HSH_DAT(tmp2, 1);
  962     CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
  963     CVMX_MT_HSH_DATZ(3);
  964     CVMX_MT_HSH_DATZ(4);
  965     CVMX_MT_HSH_DATZ(5);
  966     CVMX_MT_HSH_DATZ(6);
  967     CVMX_ES64(tmp1, ((64 + 16) << 3));
  968     CVMX_MT_HSH_STARTMD5(tmp1);
  969 
  970     /* save the HMAC */
  971     IOV_INIT(iov, data32, data_i, data_l);
  972     while (icv_off > 0) {
  973         IOV_CONSUME(iov, data32, data_i, data_l);
  974         icv_off -= 4;
  975     }
  976     CVMX_MF_HSH_IV(tmp1, 0);
  977     *data32 = (uint32_t) (tmp1 >> 32);
  978     IOV_CONSUME(iov, data32, data_i, data_l);
  979     *data32 = (uint32_t) tmp1;
  980     IOV_CONSUME(iov, data32, data_i, data_l);
  981     CVMX_MF_HSH_IV(tmp1, 1);
  982     *data32 = (uint32_t) (tmp1 >> 32);
  983 
  984     octeon_crypto_disable(s);
  985     return 0;
  986 }
  987 
  988 int
  989 octo_des_cbc_md5_decrypt(
  990     struct octo_sess *od,
  991     struct iovec *iov, size_t iovcnt, size_t iovlen,
  992     int auth_off, int auth_len,
  993     int crypt_off, int crypt_len,
  994     int icv_off, uint8_t *ivp)
  995 {
  996     register int next = 0;
  997     union {
  998         uint32_t data32[2];
  999         uint64_t data64[1];
 1000     } mydata;
 1001     uint64_t *data = &mydata.data64[0];
 1002     uint32_t *data32;
 1003     uint64_t tmp1, tmp2;
 1004     int data_i, data_l, alen = auth_len;
 1005     register_t s;
 1006 
 1007     dprintf("%s()\n", __func__);
 1008 
 1009     if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL ||
 1010             (crypt_off & 0x3) || (crypt_off + crypt_len > iovlen) ||
 1011             (crypt_len  & 0x7) ||
 1012             (auth_len  & 0x7) ||
 1013             (auth_off & 0x3) || (auth_off + auth_len > iovlen))) {
 1014         dprintf("%s: Bad parameters od=%p iov=%p iovlen=%d "
 1015                 "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
 1016                 "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen,
 1017                 auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
 1018         return -EINVAL;
 1019     }
 1020 
 1021     IOV_INIT(iov, data32, data_i, data_l);
 1022 
 1023     CVMX_PREFETCH0(ivp);
 1024     CVMX_PREFETCH0(od->octo_enckey);
 1025 
 1026     s = octeon_crypto_enable();
 1027 
 1028     /* load 3DES Key */
 1029     CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
 1030     if (od->octo_encklen == 24) {
 1031         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
 1032         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
 1033     } else if (od->octo_encklen == 8) {
 1034         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
 1035         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
 1036     } else {
 1037         octeon_crypto_disable(s);
 1038         dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen);
 1039         return -EINVAL;
 1040     }
 1041 
 1042     CVMX_MT_3DES_IV(* (uint64_t *) ivp);
 1043 
 1044     /* Load MD5 IV */
 1045     CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
 1046     CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
 1047 
 1048     while (crypt_off > 0 && auth_off > 0) {
 1049         IOV_CONSUME(iov, data32, data_i, data_l);
 1050         crypt_off -= 4;
 1051         auth_off -= 4;
 1052     }
 1053 
 1054     while (crypt_len > 0 || auth_len > 0) {
 1055         uint32_t *first = data32;
 1056         mydata.data32[0] = *first;
 1057         IOV_CONSUME(iov, data32, data_i, data_l);
 1058         mydata.data32[1] = *data32;
 1059         if (auth_off <= 0) {
 1060             if (auth_len > 0) {
 1061                 CVM_LOAD_MD5_UNIT(*data, next);
 1062                 auth_len -= 8;
 1063             }
 1064         } else
 1065             auth_off -= 8;
 1066         if (crypt_off <= 0) {
 1067             if (crypt_len > 0) {
 1068                 CVMX_MT_3DES_DEC_CBC(*data);
 1069                 CVMX_MF_3DES_RESULT(*data);
 1070                 crypt_len -= 8;
 1071             }
 1072         } else
 1073             crypt_off -= 8;
 1074         *first = mydata.data32[0];
 1075         *data32 = mydata.data32[1];
 1076         IOV_CONSUME(iov, data32, data_i, data_l);
 1077     }
 1078 
 1079     /* finish the hash */
 1080     CVMX_PREFETCH0(od->octo_hmouter);
 1081 #if 0
 1082     if (__predict_false(inplen)) {
 1083         uint64_t tmp = 0;
 1084         uint8_t *p = (uint8_t *) & tmp;
 1085         p[inplen] = 0x80;
 1086         do {
 1087             inplen--;
 1088             p[inplen] = ((uint8_t *) data)[inplen];
 1089         } while (inplen);
 1090         CVM_LOAD_MD5_UNIT(tmp, next);
 1091     } else {
 1092         CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
 1093     }
 1094 #else
 1095     CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
 1096 #endif
 1097 
 1098     /* Finish Inner hash */
 1099     while (next != 7) {
 1100         CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
 1101     }
 1102     CVMX_ES64(tmp1, ((alen + 64) << 3));
 1103     CVM_LOAD_MD5_UNIT(tmp1, next);
 1104 
 1105     /* Get the inner hash of HMAC */
 1106     CVMX_MF_HSH_IV(tmp1, 0);
 1107     CVMX_MF_HSH_IV(tmp2, 1);
 1108 
 1109     /* Initialize hash unit */
 1110     CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
 1111     CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
 1112 
 1113     CVMX_MT_HSH_DAT(tmp1, 0);
 1114     CVMX_MT_HSH_DAT(tmp2, 1);
 1115     CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
 1116     CVMX_MT_HSH_DATZ(3);
 1117     CVMX_MT_HSH_DATZ(4);
 1118     CVMX_MT_HSH_DATZ(5);
 1119     CVMX_MT_HSH_DATZ(6);
 1120     CVMX_ES64(tmp1, ((64 + 16) << 3));
 1121     CVMX_MT_HSH_STARTMD5(tmp1);
 1122 
 1123     /* save the HMAC */
 1124     IOV_INIT(iov, data32, data_i, data_l);
 1125     while (icv_off > 0) {
 1126         IOV_CONSUME(iov, data32, data_i, data_l);
 1127         icv_off -= 4;
 1128     }
 1129     CVMX_MF_HSH_IV(tmp1, 0);
 1130     *data32 = (uint32_t) (tmp1 >> 32);
 1131     IOV_CONSUME(iov, data32, data_i, data_l);
 1132     *data32 = (uint32_t) tmp1;
 1133     IOV_CONSUME(iov, data32, data_i, data_l);
 1134     CVMX_MF_HSH_IV(tmp1, 1);
 1135     *data32 = (uint32_t) (tmp1 >> 32);
 1136 
 1137     octeon_crypto_disable(s);
 1138     return 0;
 1139 }
 1140 
 1141 /****************************************************************************/
 1142 /* DES SHA */
 1143 
 1144 int
 1145 octo_des_cbc_sha1_encrypt(
 1146     struct octo_sess *od,
 1147     struct iovec *iov, size_t iovcnt, size_t iovlen,
 1148     int auth_off, int auth_len,
 1149     int crypt_off, int crypt_len,
 1150     int icv_off, uint8_t *ivp)
 1151 {
 1152     register int next = 0;
 1153     union {
 1154         uint32_t data32[2];
 1155         uint64_t data64[1];
 1156     } mydata;
 1157     uint64_t *data = &mydata.data64[0];
 1158     uint32_t *data32;
 1159     uint64_t tmp1, tmp2, tmp3;
 1160     int data_i, data_l, alen = auth_len;
 1161     register_t s;
 1162 
 1163     dprintf("%s()\n", __func__);
 1164 
 1165     if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL ||
 1166             (crypt_off & 0x3) || (crypt_off + crypt_len > iovlen) ||
 1167             (crypt_len  & 0x7) ||
 1168             (auth_len  & 0x7) ||
 1169             (auth_off & 0x3) || (auth_off + auth_len > iovlen))) {
 1170         dprintf("%s: Bad parameters od=%p iov=%p iovlen=%d "
 1171                 "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
 1172                 "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen,
 1173                 auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
 1174         return -EINVAL;
 1175     }
 1176 
 1177     IOV_INIT(iov, data32, data_i, data_l);
 1178 
 1179     CVMX_PREFETCH0(ivp);
 1180     CVMX_PREFETCH0(od->octo_enckey);
 1181 
 1182     s = octeon_crypto_enable();
 1183 
 1184     /* load 3DES Key */
 1185     CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
 1186     if (od->octo_encklen == 24) {
 1187         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
 1188         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
 1189     } else if (od->octo_encklen == 8) {
 1190         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
 1191         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
 1192     } else {
 1193         octeon_crypto_disable(s);
 1194         dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen);
 1195         return -EINVAL;
 1196     }
 1197 
 1198     CVMX_MT_3DES_IV(* (uint64_t *) ivp);
 1199 
 1200     /* Load SHA1 IV */
 1201     CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
 1202     CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
 1203     CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
 1204 
 1205     while (crypt_off > 0 && auth_off > 0) {
 1206         IOV_CONSUME(iov, data32, data_i, data_l);
 1207         crypt_off -= 4;
 1208         auth_off -= 4;
 1209     }
 1210 
 1211     while (crypt_len > 0 || auth_len > 0) {
 1212         uint32_t *first = data32;
 1213         mydata.data32[0] = *first;
 1214         IOV_CONSUME(iov, data32, data_i, data_l);
 1215         mydata.data32[1] = *data32;
 1216         if (crypt_off <= 0) {
 1217             if (crypt_len > 0) {
 1218                 CVMX_MT_3DES_ENC_CBC(*data);
 1219                 CVMX_MF_3DES_RESULT(*data);
 1220                 crypt_len -= 8;
 1221             }
 1222         } else
 1223             crypt_off -= 8;
 1224         if (auth_off <= 0) {
 1225             if (auth_len > 0) {
 1226                 CVM_LOAD_SHA_UNIT(*data, next);
 1227                 auth_len -= 8;
 1228             }
 1229         } else
 1230             auth_off -= 8;
 1231         *first = mydata.data32[0];
 1232         *data32 = mydata.data32[1];
 1233         IOV_CONSUME(iov, data32, data_i, data_l);
 1234     }
 1235 
 1236     /* finish the hash */
 1237     CVMX_PREFETCH0(od->octo_hmouter);
 1238 #if 0
 1239     if (__predict_false(inplen)) {
 1240         uint64_t tmp = 0;
 1241         uint8_t *p = (uint8_t *) & tmp;
 1242         p[inplen] = 0x80;
 1243         do {
 1244             inplen--;
 1245             p[inplen] = ((uint8_t *) data)[inplen];
 1246         } while (inplen);
 1247         CVM_LOAD_SHA_UNIT(tmp, next);
 1248     } else {
 1249         CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
 1250     }
 1251 #else
 1252     CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
 1253 #endif
 1254 
 1255     /* Finish Inner hash */
 1256     while (next != 7) {
 1257         CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
 1258     }
 1259         CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
 1260 
 1261     /* Get the inner hash of HMAC */
 1262     CVMX_MF_HSH_IV(tmp1, 0);
 1263     CVMX_MF_HSH_IV(tmp2, 1);
 1264     tmp3 = 0;
 1265     CVMX_MF_HSH_IV(tmp3, 2);
 1266 
 1267     /* Initialize hash unit */
 1268     CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
 1269     CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
 1270     CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
 1271 
 1272     CVMX_MT_HSH_DAT(tmp1, 0);
 1273     CVMX_MT_HSH_DAT(tmp2, 1);
 1274     tmp3 |= 0x0000000080000000;
 1275     CVMX_MT_HSH_DAT(tmp3, 2);
 1276     CVMX_MT_HSH_DATZ(3);
 1277     CVMX_MT_HSH_DATZ(4);
 1278     CVMX_MT_HSH_DATZ(5);
 1279     CVMX_MT_HSH_DATZ(6);
 1280     CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
 1281 
 1282     /* save the HMAC */
 1283     IOV_INIT(iov, data32, data_i, data_l);
 1284     while (icv_off > 0) {
 1285         IOV_CONSUME(iov, data32, data_i, data_l);
 1286         icv_off -= 4;
 1287     }
 1288     CVMX_MF_HSH_IV(tmp1, 0);
 1289     *data32 = (uint32_t) (tmp1 >> 32);
 1290     IOV_CONSUME(iov, data32, data_i, data_l);
 1291     *data32 = (uint32_t) tmp1;
 1292     IOV_CONSUME(iov, data32, data_i, data_l);
 1293     CVMX_MF_HSH_IV(tmp1, 1);
 1294     *data32 = (uint32_t) (tmp1 >> 32);
 1295 
 1296     octeon_crypto_disable(s);
 1297     return 0;
 1298 }
 1299 
 1300 int
 1301 octo_des_cbc_sha1_decrypt(
 1302     struct octo_sess *od,
 1303     struct iovec *iov, size_t iovcnt, size_t iovlen,
 1304     int auth_off, int auth_len,
 1305     int crypt_off, int crypt_len,
 1306     int icv_off, uint8_t *ivp)
 1307 {
 1308     register int next = 0;
 1309     union {
 1310         uint32_t data32[2];
 1311         uint64_t data64[1];
 1312     } mydata;
 1313     uint64_t *data = &mydata.data64[0];
 1314     uint32_t *data32;
 1315     uint64_t tmp1, tmp2, tmp3;
 1316     int data_i, data_l, alen = auth_len;
 1317     register_t s;
 1318 
 1319     dprintf("%s()\n", __func__);
 1320 
 1321     if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL ||
 1322             (crypt_off & 0x3) || (crypt_off + crypt_len > iovlen) ||
 1323             (crypt_len  & 0x7) ||
 1324             (auth_len  & 0x7) ||
 1325             (auth_off & 0x3) || (auth_off + auth_len > iovlen))) {
 1326         dprintf("%s: Bad parameters od=%p iov=%p iovlen=%d "
 1327                 "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
 1328                 "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen,
 1329                 auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
 1330         return -EINVAL;
 1331     }
 1332 
 1333     IOV_INIT(iov, data32, data_i, data_l);
 1334 
 1335     CVMX_PREFETCH0(ivp);
 1336     CVMX_PREFETCH0(od->octo_enckey);
 1337 
 1338     s = octeon_crypto_enable();
 1339 
 1340     /* load 3DES Key */
 1341     CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
 1342     if (od->octo_encklen == 24) {
 1343         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
 1344         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
 1345     } else if (od->octo_encklen == 8) {
 1346         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
 1347         CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
 1348     } else {
 1349         octeon_crypto_disable(s);
 1350         dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen);
 1351         return -EINVAL;
 1352     }
 1353 
 1354     CVMX_MT_3DES_IV(* (uint64_t *) ivp);
 1355 
 1356     /* Load SHA1 IV */
 1357     CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
 1358     CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
 1359     CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
 1360 
 1361     while (crypt_off > 0 && auth_off > 0) {
 1362         IOV_CONSUME(iov, data32, data_i, data_l);
 1363         crypt_off -= 4;
 1364         auth_off -= 4;
 1365     }
 1366 
 1367     while (crypt_len > 0 || auth_len > 0) {
 1368         uint32_t *first = data32;
 1369         mydata.data32[0] = *first;
 1370         IOV_CONSUME(iov, data32, data_i, data_l);
 1371         mydata.data32[1] = *data32;
 1372         if (auth_off <= 0) {
 1373             if (auth_len > 0) {
 1374                 CVM_LOAD_SHA_UNIT(*data, next);
 1375                 auth_len -= 8;
 1376             }
 1377         } else
 1378             auth_off -= 8;
 1379         if (crypt_off <= 0) {
 1380             if (crypt_len > 0) {
 1381                 CVMX_MT_3DES_DEC_CBC(*data);
 1382                 CVMX_MF_3DES_RESULT(*data);
 1383                 crypt_len -= 8;
 1384             }
 1385         } else
 1386             crypt_off -= 8;
 1387         *first = mydata.data32[0];
 1388         *data32 = mydata.data32[1];
 1389         IOV_CONSUME(iov, data32, data_i, data_l);
 1390     }
 1391 
 1392     /* finish the hash */
 1393     CVMX_PREFETCH0(od->octo_hmouter);
 1394 #if 0
 1395     if (__predict_false(inplen)) {
 1396         uint64_t tmp = 0;
 1397         uint8_t *p = (uint8_t *) & tmp;
 1398         p[inplen] = 0x80;
 1399         do {
 1400             inplen--;
 1401             p[inplen] = ((uint8_t *) data)[inplen];
 1402         } while (inplen);
 1403         CVM_LOAD_SHA_UNIT(tmp, next);
 1404     } else {
 1405         CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
 1406     }
 1407 #else
 1408     CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
 1409 #endif
 1410 
 1411     /* Finish Inner hash */
 1412     while (next != 7) {
 1413         CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
 1414     }
 1415         CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
 1416 
 1417     /* Get the inner hash of HMAC */
 1418     CVMX_MF_HSH_IV(tmp1, 0);
 1419     CVMX_MF_HSH_IV(tmp2, 1);
 1420     tmp3 = 0;
 1421     CVMX_MF_HSH_IV(tmp3, 2);
 1422 
 1423     /* Initialize hash unit */
 1424     CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
 1425     CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
 1426     CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
 1427 
 1428     CVMX_MT_HSH_DAT(tmp1, 0);
 1429     CVMX_MT_HSH_DAT(tmp2, 1);
 1430     tmp3 |= 0x0000000080000000;
 1431     CVMX_MT_HSH_DAT(tmp3, 2);
 1432     CVMX_MT_HSH_DATZ(3);
 1433     CVMX_MT_HSH_DATZ(4);
 1434     CVMX_MT_HSH_DATZ(5);
 1435     CVMX_MT_HSH_DATZ(6);
 1436     CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
 1437     /* save the HMAC */
 1438     IOV_INIT(iov, data32, data_i, data_l);
 1439     while (icv_off > 0) {
 1440         IOV_CONSUME(iov, data32, data_i, data_l);
 1441         icv_off -= 4;
 1442     }
 1443     CVMX_MF_HSH_IV(tmp1, 0);
 1444     *data32 = (uint32_t) (tmp1 >> 32);
 1445     IOV_CONSUME(iov, data32, data_i, data_l);
 1446     *data32 = (uint32_t) tmp1;
 1447     IOV_CONSUME(iov, data32, data_i, data_l);
 1448     CVMX_MF_HSH_IV(tmp1, 1);
 1449     *data32 = (uint32_t) (tmp1 >> 32);
 1450 
 1451     octeon_crypto_disable(s);
 1452     return 0;
 1453 }
 1454 
 1455 /****************************************************************************/
 1456 /* AES MD5 */
 1457 
 1458 int
 1459 octo_aes_cbc_md5_encrypt(
 1460     struct octo_sess *od,
 1461     struct iovec *iov, size_t iovcnt, size_t iovlen,
 1462     int auth_off, int auth_len,
 1463     int crypt_off, int crypt_len,
 1464     int icv_off, uint8_t *ivp)
 1465 {
 1466     register int next = 0;
 1467     union {
 1468         uint32_t data32[2];
 1469         uint64_t data64[1];
 1470     } mydata[2];
 1471     uint64_t *pdata = &mydata[0].data64[0];
 1472     uint64_t *data =  &mydata[1].data64[0];
 1473     uint32_t *data32;
 1474     uint64_t tmp1, tmp2;
 1475     int data_i, data_l, alen = auth_len;
 1476     register_t s;
 1477 
 1478     dprintf("%s()\n", __func__);
 1479 
 1480     if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL ||
 1481             (crypt_off & 0x3) || (crypt_off + crypt_len > iovlen) ||
 1482             (crypt_len  & 0x7) ||
 1483             (auth_len  & 0x7) ||
 1484             (auth_off & 0x3) || (auth_off + auth_len > iovlen))) {
 1485         dprintf("%s: Bad parameters od=%p iov=%p iovlen=%d "
 1486                 "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
 1487                 "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen,
 1488                 auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
 1489         return -EINVAL;
 1490     }
 1491 
 1492     IOV_INIT(iov, data32, data_i, data_l);
 1493 
 1494     CVMX_PREFETCH0(ivp);
 1495     CVMX_PREFETCH0(od->octo_enckey);
 1496 
 1497     s = octeon_crypto_enable();
 1498 
 1499     /* load AES Key */
 1500     CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
 1501     CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
 1502 
 1503     if (od->octo_encklen == 16) {
 1504         CVMX_MT_AES_KEY(0x0, 2);
 1505         CVMX_MT_AES_KEY(0x0, 3);
 1506     } else if (od->octo_encklen == 24) {
 1507         CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
 1508         CVMX_MT_AES_KEY(0x0, 3);
 1509     } else if (od->octo_encklen == 32) {
 1510         CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
 1511         CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
 1512     } else {
 1513         octeon_crypto_disable(s);
 1514         dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen);
 1515         return -EINVAL;
 1516     }
 1517     CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
 1518 
 1519     CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
 1520     CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
 1521 
 1522     /* Load MD5 IV */
 1523     CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
 1524     CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
 1525 
 1526     while (crypt_off > 0 && auth_off > 0) {
 1527         IOV_CONSUME(iov, data32, data_i, data_l);
 1528         crypt_off -= 4;
 1529         auth_off -= 4;
 1530     }
 1531 
 1532     while (crypt_len > 0 || auth_len > 0) {
 1533         uint32_t *pdata32[3];
 1534 
 1535         pdata32[0] = data32;
 1536         mydata[0].data32[0] = *data32;
 1537         IOV_CONSUME(iov, data32, data_i, data_l);
 1538 
 1539         pdata32[1] = data32;
 1540         mydata[0].data32[1] = *data32;
 1541         IOV_CONSUME(iov, data32, data_i, data_l);
 1542 
 1543         pdata32[2] = data32;
 1544         mydata[1].data32[0] = *data32;
 1545         IOV_CONSUME(iov, data32, data_i, data_l);
 1546 
 1547         mydata[1].data32[1] = *data32;
 1548 
 1549 
 1550         if (crypt_off <= 0) {
 1551             if (crypt_len > 0) {
 1552                 CVMX_MT_AES_ENC_CBC0(*pdata);
 1553                 CVMX_MT_AES_ENC_CBC1(*data);
 1554                 CVMX_MF_AES_RESULT(*pdata, 0);
 1555                 CVMX_MF_AES_RESULT(*data, 1);
 1556                 crypt_len -= 16;
 1557             }
 1558         } else
 1559             crypt_off -= 16;
 1560 
 1561         if (auth_off <= 0) {
 1562             if (auth_len > 0) {
 1563                 CVM_LOAD_MD5_UNIT(*pdata, next);
 1564                 CVM_LOAD_MD5_UNIT(*data, next);
 1565                 auth_len -= 16;
 1566             }
 1567         } else
 1568             auth_off -= 16;
 1569 
 1570         *pdata32[0] = mydata[0].data32[0];
 1571         *pdata32[1] = mydata[0].data32[1];
 1572         *pdata32[2] = mydata[1].data32[0];
 1573         *data32     = mydata[1].data32[1];
 1574 
 1575         IOV_CONSUME(iov, data32, data_i, data_l);
 1576     }
 1577 
 1578     /* finish the hash */
 1579     CVMX_PREFETCH0(od->octo_hmouter);
 1580 #if 0
 1581     if (__predict_false(inplen)) {
 1582         uint64_t tmp = 0;
 1583         uint8_t *p = (uint8_t *) & tmp;
 1584         p[inplen] = 0x80;
 1585         do {
 1586             inplen--;
 1587             p[inplen] = ((uint8_t *) data)[inplen];
 1588         } while (inplen);
 1589         CVM_LOAD_MD5_UNIT(tmp, next);
 1590     } else {
 1591         CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
 1592     }
 1593 #else
 1594     CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
 1595 #endif
 1596 
 1597     /* Finish Inner hash */
 1598     while (next != 7) {
 1599         CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
 1600     }
 1601     CVMX_ES64(tmp1, ((alen + 64) << 3));
 1602     CVM_LOAD_MD5_UNIT(tmp1, next);
 1603 
 1604     /* Get the inner hash of HMAC */
 1605     CVMX_MF_HSH_IV(tmp1, 0);
 1606     CVMX_MF_HSH_IV(tmp2, 1);
 1607 
 1608     /* Initialize hash unit */
 1609     CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
 1610     CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
 1611 
 1612     CVMX_MT_HSH_DAT(tmp1, 0);
 1613     CVMX_MT_HSH_DAT(tmp2, 1);
 1614     CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
 1615     CVMX_MT_HSH_DATZ(3);
 1616     CVMX_MT_HSH_DATZ(4);
 1617     CVMX_MT_HSH_DATZ(5);
 1618     CVMX_MT_HSH_DATZ(6);
 1619     CVMX_ES64(tmp1, ((64 + 16) << 3));
 1620     CVMX_MT_HSH_STARTMD5(tmp1);
 1621 
 1622     /* save the HMAC */
 1623     IOV_INIT(iov, data32, data_i, data_l);
 1624     while (icv_off > 0) {
 1625         IOV_CONSUME(iov, data32, data_i, data_l);
 1626         icv_off -= 4;
 1627     }
 1628     CVMX_MF_HSH_IV(tmp1, 0);
 1629     *data32 = (uint32_t) (tmp1 >> 32);
 1630     IOV_CONSUME(iov, data32, data_i, data_l);
 1631     *data32 = (uint32_t) tmp1;
 1632     IOV_CONSUME(iov, data32, data_i, data_l);
 1633     CVMX_MF_HSH_IV(tmp1, 1);
 1634     *data32 = (uint32_t) (tmp1 >> 32);
 1635 
 1636     octeon_crypto_disable(s);
 1637     return 0;
 1638 }
 1639 
 1640 int
 1641 octo_aes_cbc_md5_decrypt(
 1642     struct octo_sess *od,
 1643     struct iovec *iov, size_t iovcnt, size_t iovlen,
 1644     int auth_off, int auth_len,
 1645     int crypt_off, int crypt_len,
 1646     int icv_off, uint8_t *ivp)
 1647 {
 1648     register int next = 0;
 1649     union {
 1650         uint32_t data32[2];
 1651         uint64_t data64[1];
 1652     } mydata[2];
 1653     uint64_t *pdata = &mydata[0].data64[0];
 1654     uint64_t *data =  &mydata[1].data64[0];
 1655     uint32_t *data32;
 1656     uint64_t tmp1, tmp2;
 1657     int data_i, data_l, alen = auth_len;
 1658     register_t s;
 1659 
 1660     dprintf("%s()\n", __func__);
 1661 
 1662     if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL ||
 1663             (crypt_off & 0x3) || (crypt_off + crypt_len > iovlen) ||
 1664             (crypt_len  & 0x7) ||
 1665             (auth_len  & 0x7) ||
 1666             (auth_off & 0x3) || (auth_off + auth_len > iovlen))) {
 1667         dprintf("%s: Bad parameters od=%p iov=%p iovlen=%d "
 1668                 "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
 1669                 "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen,
 1670                 auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
 1671         return -EINVAL;
 1672     }
 1673 
 1674     IOV_INIT(iov, data32, data_i, data_l);
 1675 
 1676     CVMX_PREFETCH0(ivp);
 1677     CVMX_PREFETCH0(od->octo_enckey);
 1678 
 1679     s = octeon_crypto_enable();
 1680 
 1681     /* load AES Key */
 1682     CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
 1683     CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
 1684 
 1685     if (od->octo_encklen == 16) {
 1686         CVMX_MT_AES_KEY(0x0, 2);
 1687         CVMX_MT_AES_KEY(0x0, 3);
 1688     } else if (od->octo_encklen == 24) {
 1689         CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
 1690         CVMX_MT_AES_KEY(0x0, 3);
 1691     } else if (od->octo_encklen == 32) {
 1692         CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
 1693         CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
 1694     } else {
 1695         octeon_crypto_disable(s);
 1696         dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen);
 1697         return -EINVAL;
 1698     }
 1699     CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
 1700 
 1701     CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
 1702     CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
 1703 
 1704     /* Load MD5 IV */
 1705     CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
 1706     CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
 1707 
 1708     while (crypt_off > 0 && auth_off > 0) {
 1709         IOV_CONSUME(iov, data32, data_i, data_l);
 1710         crypt_off -= 4;
 1711         auth_off -= 4;
 1712     }
 1713 
 1714     while (crypt_len > 0 || auth_len > 0) {
 1715         uint32_t *pdata32[3];
 1716 
 1717         pdata32[0] = data32;
 1718         mydata[0].data32[0] = *data32;
 1719         IOV_CONSUME(iov, data32, data_i, data_l);
 1720         pdata32[1] = data32;
 1721         mydata[0].data32[1] = *data32;
 1722         IOV_CONSUME(iov, data32, data_i, data_l);
 1723         pdata32[2] = data32;
 1724         mydata[1].data32[0] = *data32;
 1725         IOV_CONSUME(iov, data32, data_i, data_l);
 1726         mydata[1].data32[1] = *data32;
 1727 
 1728         if (auth_off <= 0) {
 1729             if (auth_len > 0) {
 1730                 CVM_LOAD_MD5_UNIT(*pdata, next);
 1731                 CVM_LOAD_MD5_UNIT(*data, next);
 1732                 auth_len -= 16;
 1733             }
 1734         } else
 1735             auth_off -= 16;
 1736 
 1737         if (crypt_off <= 0) {
 1738             if (crypt_len > 0) {
 1739                 CVMX_MT_AES_DEC_CBC0(*pdata);
 1740                 CVMX_MT_AES_DEC_CBC1(*data);
 1741                 CVMX_MF_AES_RESULT(*pdata, 0);
 1742                 CVMX_MF_AES_RESULT(*data, 1);
 1743                 crypt_len -= 16;
 1744             }
 1745         } else
 1746             crypt_off -= 16;
 1747 
 1748         *pdata32[0] = mydata[0].data32[0];
 1749         *pdata32[1] = mydata[0].data32[1];
 1750         *pdata32[2] = mydata[1].data32[0];
 1751         *data32     = mydata[1].data32[1];
 1752 
 1753         IOV_CONSUME(iov, data32, data_i, data_l);
 1754     }
 1755 
 1756     /* finish the hash */
 1757     CVMX_PREFETCH0(od->octo_hmouter);
 1758 #if 0
 1759     if (__predict_false(inplen)) {
 1760         uint64_t tmp = 0;
 1761         uint8_t *p = (uint8_t *) & tmp;
 1762         p[inplen] = 0x80;
 1763         do {
 1764             inplen--;
 1765             p[inplen] = ((uint8_t *) data)[inplen];
 1766         } while (inplen);
 1767         CVM_LOAD_MD5_UNIT(tmp, next);
 1768     } else {
 1769         CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
 1770     }
 1771 #else
 1772     CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
 1773 #endif
 1774 
 1775     /* Finish Inner hash */
 1776     while (next != 7) {
 1777         CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
 1778     }
 1779     CVMX_ES64(tmp1, ((alen + 64) << 3));
 1780     CVM_LOAD_MD5_UNIT(tmp1, next);
 1781 
 1782     /* Get the inner hash of HMAC */
 1783     CVMX_MF_HSH_IV(tmp1, 0);
 1784     CVMX_MF_HSH_IV(tmp2, 1);
 1785 
 1786     /* Initialize hash unit */
 1787     CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
 1788     CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
 1789 
 1790     CVMX_MT_HSH_DAT(tmp1, 0);
 1791     CVMX_MT_HSH_DAT(tmp2, 1);
 1792     CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
 1793     CVMX_MT_HSH_DATZ(3);
 1794     CVMX_MT_HSH_DATZ(4);
 1795     CVMX_MT_HSH_DATZ(5);
 1796     CVMX_MT_HSH_DATZ(6);
 1797     CVMX_ES64(tmp1, ((64 + 16) << 3));
 1798     CVMX_MT_HSH_STARTMD5(tmp1);
 1799 
 1800     /* save the HMAC */
 1801     IOV_INIT(iov, data32, data_i, data_l);
 1802     while (icv_off > 0) {
 1803         IOV_CONSUME(iov, data32, data_i, data_l);
 1804         icv_off -= 4;
 1805     }
 1806     CVMX_MF_HSH_IV(tmp1, 0);
 1807     *data32 = (uint32_t) (tmp1 >> 32);
 1808     IOV_CONSUME(iov, data32, data_i, data_l);
 1809     *data32 = (uint32_t) tmp1;
 1810     IOV_CONSUME(iov, data32, data_i, data_l);
 1811     CVMX_MF_HSH_IV(tmp1, 1);
 1812     *data32 = (uint32_t) (tmp1 >> 32);
 1813 
 1814     octeon_crypto_disable(s);
 1815     return 0;
 1816 }
 1817 
 1818 /****************************************************************************/
 1819 /* AES SHA1 */
 1820 
 1821 int
 1822 octo_aes_cbc_sha1_encrypt(
 1823     struct octo_sess *od,
 1824     struct iovec *iov, size_t iovcnt, size_t iovlen,
 1825     int auth_off, int auth_len,
 1826     int crypt_off, int crypt_len,
 1827     int icv_off, uint8_t *ivp)
 1828 {
 1829     register int next = 0;
 1830     union {
 1831         uint32_t data32[2];
 1832         uint64_t data64[1];
 1833     } mydata[2];
 1834     uint64_t *pdata = &mydata[0].data64[0];
 1835     uint64_t *data =  &mydata[1].data64[0];
 1836     uint32_t *data32;
 1837     uint64_t tmp1, tmp2, tmp3;
 1838     int data_i, data_l, alen = auth_len;
 1839     register_t s;
 1840 
 1841     dprintf("%s()\n", __func__);
 1842 
 1843     if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL ||
 1844             (crypt_off & 0x3) || (crypt_off + crypt_len > iovlen) ||
 1845             (crypt_len  & 0x7) ||
 1846             (auth_len  & 0x7) ||
 1847             (auth_off & 0x3) || (auth_off + auth_len > iovlen))) {
 1848         dprintf("%s: Bad parameters od=%p iov=%p iovlen=%d "
 1849                 "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
 1850                 "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen,
 1851                 auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
 1852         return -EINVAL;
 1853     }
 1854 
 1855     IOV_INIT(iov, data32, data_i, data_l);
 1856 
 1857     CVMX_PREFETCH0(ivp);
 1858     CVMX_PREFETCH0(od->octo_enckey);
 1859 
 1860     s = octeon_crypto_enable();
 1861 
 1862     /* load AES Key */
 1863     CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
 1864     CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
 1865 
 1866     if (od->octo_encklen == 16) {
 1867         CVMX_MT_AES_KEY(0x0, 2);
 1868         CVMX_MT_AES_KEY(0x0, 3);
 1869     } else if (od->octo_encklen == 24) {
 1870         CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
 1871         CVMX_MT_AES_KEY(0x0, 3);
 1872     } else if (od->octo_encklen == 32) {
 1873         CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
 1874         CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
 1875     } else {
 1876         octeon_crypto_disable(s);
 1877         dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen);
 1878         return -EINVAL;
 1879     }
 1880     CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
 1881 
 1882     CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
 1883     CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
 1884 
 1885     /* Load SHA IV */
 1886     CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
 1887     CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
 1888     CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
 1889 
 1890     while (crypt_off > 0 && auth_off > 0) {
 1891         IOV_CONSUME(iov, data32, data_i, data_l);
 1892         crypt_off -= 4;
 1893         auth_off -= 4;
 1894     }
 1895 
 1896     while (crypt_len > 0 || auth_len > 0) {
 1897         uint32_t *pdata32[3];
 1898 
 1899         pdata32[0] = data32;
 1900         mydata[0].data32[0] = *data32;
 1901         IOV_CONSUME(iov, data32, data_i, data_l);
 1902         pdata32[1] = data32;
 1903         mydata[0].data32[1] = *data32;
 1904         IOV_CONSUME(iov, data32, data_i, data_l);
 1905         pdata32[2] = data32;
 1906         mydata[1].data32[0] = *data32;
 1907         IOV_CONSUME(iov, data32, data_i, data_l);
 1908         mydata[1].data32[1] = *data32;
 1909 
 1910 
 1911         if (crypt_off <= 0) {
 1912             if (crypt_len > 0) {
 1913                 CVMX_MT_AES_ENC_CBC0(*pdata);
 1914                 CVMX_MT_AES_ENC_CBC1(*data);
 1915                 CVMX_MF_AES_RESULT(*pdata, 0);
 1916                 CVMX_MF_AES_RESULT(*data, 1);
 1917                 crypt_len -= 16;
 1918             }
 1919         } else
 1920             crypt_off -= 16;
 1921 
 1922         if (auth_off <= 0) {
 1923             if (auth_len > 0) {
 1924                 CVM_LOAD_SHA_UNIT(*pdata, next);
 1925                 CVM_LOAD_SHA_UNIT(*data, next);
 1926                 auth_len -= 16;
 1927             }
 1928         } else
 1929             auth_off -= 16;
 1930 
 1931         *pdata32[0] = mydata[0].data32[0];
 1932         *pdata32[1] = mydata[0].data32[1];
 1933         *pdata32[2] = mydata[1].data32[0];
 1934         *data32     = mydata[1].data32[1];
 1935 
 1936         IOV_CONSUME(iov, data32, data_i, data_l);
 1937     }
 1938 
 1939     /* finish the hash */
 1940     CVMX_PREFETCH0(od->octo_hmouter);
 1941 #if 0
 1942     if (__predict_false(inplen)) {
 1943         uint64_t tmp = 0;
 1944         uint8_t *p = (uint8_t *) & tmp;
 1945         p[inplen] = 0x80;
 1946         do {
 1947             inplen--;
 1948             p[inplen] = ((uint8_t *) data)[inplen];
 1949         } while (inplen);
 1950         CVM_LOAD_SHA_UNIT(tmp, next);
 1951     } else {
 1952         CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
 1953     }
 1954 #else
 1955     CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
 1956 #endif
 1957 
 1958     /* Finish Inner hash */
 1959     while (next != 7) {
 1960         CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
 1961     }
 1962         CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
 1963 
 1964     /* Get the inner hash of HMAC */
 1965     CVMX_MF_HSH_IV(tmp1, 0);
 1966     CVMX_MF_HSH_IV(tmp2, 1);
 1967     tmp3 = 0;
 1968     CVMX_MF_HSH_IV(tmp3, 2);
 1969 
 1970     /* Initialize hash unit */
 1971     CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
 1972     CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
 1973     CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
 1974 
 1975     CVMX_MT_HSH_DAT(tmp1, 0);
 1976     CVMX_MT_HSH_DAT(tmp2, 1);
 1977     tmp3 |= 0x0000000080000000;
 1978     CVMX_MT_HSH_DAT(tmp3, 2);
 1979     CVMX_MT_HSH_DATZ(3);
 1980     CVMX_MT_HSH_DATZ(4);
 1981     CVMX_MT_HSH_DATZ(5);
 1982     CVMX_MT_HSH_DATZ(6);
 1983     CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
 1984 
 1985     /* finish the hash */
 1986     CVMX_PREFETCH0(od->octo_hmouter);
 1987 #if 0
 1988     if (__predict_false(inplen)) {
 1989         uint64_t tmp = 0;
 1990         uint8_t *p = (uint8_t *) & tmp;
 1991         p[inplen] = 0x80;
 1992         do {
 1993             inplen--;
 1994             p[inplen] = ((uint8_t *) data)[inplen];
 1995         } while (inplen);
 1996         CVM_LOAD_MD5_UNIT(tmp, next);
 1997     } else {
 1998         CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
 1999     }
 2000 #else
 2001     CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
 2002 #endif
 2003 
 2004     /* save the HMAC */
 2005     IOV_INIT(iov, data32, data_i, data_l);
 2006     while (icv_off > 0) {
 2007         IOV_CONSUME(iov, data32, data_i, data_l);
 2008         icv_off -= 4;
 2009     }
 2010     CVMX_MF_HSH_IV(tmp1, 0);
 2011     *data32 = (uint32_t) (tmp1 >> 32);
 2012     IOV_CONSUME(iov, data32, data_i, data_l);
 2013     *data32 = (uint32_t) tmp1;
 2014     IOV_CONSUME(iov, data32, data_i, data_l);
 2015     CVMX_MF_HSH_IV(tmp1, 1);
 2016     *data32 = (uint32_t) (tmp1 >> 32);
 2017 
 2018     octeon_crypto_disable(s);
 2019     return 0;
 2020 }
 2021 
 2022 int
 2023 octo_aes_cbc_sha1_decrypt(
 2024     struct octo_sess *od,
 2025     struct iovec *iov, size_t iovcnt, size_t iovlen,
 2026     int auth_off, int auth_len,
 2027     int crypt_off, int crypt_len,
 2028     int icv_off, uint8_t *ivp)
 2029 {
 2030     register int next = 0;
 2031     union {
 2032         uint32_t data32[2];
 2033         uint64_t data64[1];
 2034     } mydata[2];
 2035     uint64_t *pdata = &mydata[0].data64[0];
 2036     uint64_t *data =  &mydata[1].data64[0];
 2037     uint32_t *data32;
 2038     uint64_t tmp1, tmp2, tmp3;
 2039     int data_i, data_l, alen = auth_len;
 2040     register_t s;
 2041 
 2042     dprintf("%s()\n", __func__);
 2043 
 2044     if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL ||
 2045             (crypt_off & 0x3) || (crypt_off + crypt_len > iovlen) ||
 2046             (crypt_len  & 0x7) ||
 2047             (auth_len  & 0x7) ||
 2048             (auth_off & 0x3) || (auth_off + auth_len > iovlen))) {
 2049         dprintf("%s: Bad parameters od=%p iov=%p iovlen=%d "
 2050                 "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
 2051                 "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen,
 2052                 auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
 2053         return -EINVAL;
 2054     }
 2055 
 2056     IOV_INIT(iov, data32, data_i, data_l);
 2057 
 2058     CVMX_PREFETCH0(ivp);
 2059     CVMX_PREFETCH0(od->octo_enckey);
 2060 
 2061     s = octeon_crypto_enable();
 2062 
 2063     /* load AES Key */
 2064     CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
 2065     CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
 2066 
 2067     if (od->octo_encklen == 16) {
 2068         CVMX_MT_AES_KEY(0x0, 2);
 2069         CVMX_MT_AES_KEY(0x0, 3);
 2070     } else if (od->octo_encklen == 24) {
 2071         CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
 2072         CVMX_MT_AES_KEY(0x0, 3);
 2073     } else if (od->octo_encklen == 32) {
 2074         CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
 2075         CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
 2076     } else {
 2077         octeon_crypto_disable(s);
 2078         dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen);
 2079         return -EINVAL;
 2080     }
 2081     CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
 2082 
 2083     CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
 2084     CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
 2085 
 2086     /* Load MD5 IV */
 2087     CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
 2088     CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
 2089     CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
 2090 
 2091     while (crypt_off > 0 && auth_off > 0) {
 2092         IOV_CONSUME(iov, data32, data_i, data_l);
 2093         crypt_off -= 4;
 2094         auth_off -= 4;
 2095     }
 2096 
 2097     while (crypt_len > 0 || auth_len > 0) {
 2098         uint32_t *pdata32[3];
 2099 
 2100         pdata32[0] = data32;
 2101         mydata[0].data32[0] = *data32;
 2102         IOV_CONSUME(iov, data32, data_i, data_l);
 2103         pdata32[1] = data32;
 2104         mydata[0].data32[1] = *data32;
 2105         IOV_CONSUME(iov, data32, data_i, data_l);
 2106         pdata32[2] = data32;
 2107         mydata[1].data32[0] = *data32;
 2108         IOV_CONSUME(iov, data32, data_i, data_l);
 2109         mydata[1].data32[1] = *data32;
 2110 
 2111         if (auth_off <= 0) {
 2112             if (auth_len > 0) {
 2113                 CVM_LOAD_SHA_UNIT(*pdata, next);
 2114                 CVM_LOAD_SHA_UNIT(*data, next);
 2115                 auth_len -= 16;
 2116             }
 2117         } else
 2118             auth_off -= 16;
 2119 
 2120         if (crypt_off <= 0) {
 2121             if (crypt_len > 0) {
 2122                 CVMX_MT_AES_DEC_CBC0(*pdata);
 2123                 CVMX_MT_AES_DEC_CBC1(*data);
 2124                 CVMX_MF_AES_RESULT(*pdata, 0);
 2125                 CVMX_MF_AES_RESULT(*data, 1);
 2126                 crypt_len -= 16;
 2127             }
 2128         } else
 2129             crypt_off -= 16;
 2130 
 2131         *pdata32[0] = mydata[0].data32[0];
 2132         *pdata32[1] = mydata[0].data32[1];
 2133         *pdata32[2] = mydata[1].data32[0];
 2134         *data32     = mydata[1].data32[1];
 2135 
 2136         IOV_CONSUME(iov, data32, data_i, data_l);
 2137     }
 2138 
 2139     /* finish the hash */
 2140     CVMX_PREFETCH0(od->octo_hmouter);
 2141 #if 0
 2142     if (__predict_false(inplen)) {
 2143         uint64_t tmp = 0;
 2144         uint8_t *p = (uint8_t *) & tmp;
 2145         p[inplen] = 0x80;
 2146         do {
 2147             inplen--;
 2148             p[inplen] = ((uint8_t *) data)[inplen];
 2149         } while (inplen);
 2150         CVM_LOAD_SHA_UNIT(tmp, next);
 2151     } else {
 2152         CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
 2153     }
 2154 #else
 2155     CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
 2156 #endif
 2157 
 2158     /* Finish Inner hash */
 2159     while (next != 7) {
 2160         CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
 2161     }
 2162         CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
 2163 
 2164     /* Get the inner hash of HMAC */
 2165     CVMX_MF_HSH_IV(tmp1, 0);
 2166     CVMX_MF_HSH_IV(tmp2, 1);
 2167     tmp3 = 0;
 2168     CVMX_MF_HSH_IV(tmp3, 2);
 2169 
 2170     /* Initialize hash unit */
 2171     CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
 2172     CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
 2173     CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
 2174 
 2175     CVMX_MT_HSH_DAT(tmp1, 0);
 2176     CVMX_MT_HSH_DAT(tmp2, 1);
 2177     tmp3 |= 0x0000000080000000;
 2178     CVMX_MT_HSH_DAT(tmp3, 2);
 2179     CVMX_MT_HSH_DATZ(3);
 2180     CVMX_MT_HSH_DATZ(4);
 2181     CVMX_MT_HSH_DATZ(5);
 2182     CVMX_MT_HSH_DATZ(6);
 2183     CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
 2184 
 2185     /* finish the hash */
 2186     CVMX_PREFETCH0(od->octo_hmouter);
 2187 #if 0
 2188     if (__predict_false(inplen)) {
 2189         uint64_t tmp = 0;
 2190         uint8_t *p = (uint8_t *) & tmp;
 2191         p[inplen] = 0x80;
 2192         do {
 2193             inplen--;
 2194             p[inplen] = ((uint8_t *) data)[inplen];
 2195         } while (inplen);
 2196         CVM_LOAD_MD5_UNIT(tmp, next);
 2197     } else {
 2198         CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
 2199     }
 2200 #else
 2201     CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
 2202 #endif
 2203 
 2204     /* save the HMAC */
 2205     IOV_INIT(iov, data32, data_i, data_l);
 2206     while (icv_off > 0) {
 2207         IOV_CONSUME(iov, data32, data_i, data_l);
 2208         icv_off -= 4;
 2209     }
 2210     CVMX_MF_HSH_IV(tmp1, 0);
 2211     *data32 = (uint32_t) (tmp1 >> 32);
 2212     IOV_CONSUME(iov, data32, data_i, data_l);
 2213     *data32 = (uint32_t) tmp1;
 2214     IOV_CONSUME(iov, data32, data_i, data_l);
 2215     CVMX_MF_HSH_IV(tmp1, 1);
 2216     *data32 = (uint32_t) (tmp1 >> 32);
 2217 
 2218     octeon_crypto_disable(s);
 2219     return 0;
 2220 }
 2221 
 2222 /****************************************************************************/

Cache object: 7ad1b2699eb3fdba113dfbae1126e12b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.