1210312Sjmallett/* 2210312Sjmallett * vim:sw=4 ts=8 3210312Sjmallett */ 4210312Sjmallett/* 5210312Sjmallett * Copyright (c) 2009 David McCullough <david.mccullough@securecomputing.com> 6210312Sjmallett * 7210312Sjmallett * Copyright (c) 2003-2007 Cavium Networks (support@cavium.com). All rights 8210312Sjmallett * reserved. 9210312Sjmallett * 10210312Sjmallett * Redistribution and use in source and binary forms, with or without 11210312Sjmallett * modification, are permitted provided that the following conditions are met: 12210312Sjmallett * 1. Redistributions of source code must retain the above copyright notice, 13210312Sjmallett * this list of conditions and the following disclaimer. 14210312Sjmallett * 2. Redistributions in binary form must reproduce the above copyright notice, 15210312Sjmallett * this list of conditions and the following disclaimer in the documentation 16210312Sjmallett * and/or other materials provided with the distribution. 17210312Sjmallett * 3. All advertising materials mentioning features or use of this software 18210312Sjmallett * must display the following acknowledgement: 19210312Sjmallett * This product includes software developed by Cavium Networks 20210312Sjmallett * 4. Cavium Networks' name may not be used to endorse or promote products 21210312Sjmallett * derived from this software without specific prior written permission. 22210312Sjmallett * 23210312Sjmallett * This Software, including technical data, may be subject to U.S. export 24210312Sjmallett * control laws, including the U.S. Export Administration Act and its 25210312Sjmallett * associated regulations, and may be subject to export or import regulations 26210312Sjmallett * in other countries. You warrant that You will comply strictly in all 27210312Sjmallett * respects with all such regulations and acknowledge that you have the 28210312Sjmallett * responsibility to obtain licenses to export, re-export or import the 29210312Sjmallett * Software. 30210312Sjmallett * 31210312Sjmallett * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" AND 32210312Sjmallett * WITH ALL FAULTS AND CAVIUM MAKES NO PROMISES, REPRESENTATIONS OR WARRANTIES, 33210312Sjmallett * EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO THE 34210312Sjmallett * SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR 35210312Sjmallett * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM 36210312Sjmallett * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, 37210312Sjmallett * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF 38210312Sjmallett * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR 39210312Sjmallett * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR 40210312Sjmallett * PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 41210312Sjmallett*/ 42210312Sjmallett/****************************************************************************/ 43210312Sjmallett 44210312Sjmallett#include <sys/cdefs.h> 45210312Sjmallett__FBSDID("$FreeBSD$"); 46210312Sjmallett 47210312Sjmallett#include <sys/param.h> 48210312Sjmallett#include <sys/systm.h> 49210312Sjmallett#include <sys/kernel.h> 50210312Sjmallett#include <sys/module.h> 51210312Sjmallett#include <sys/malloc.h> 52210312Sjmallett#include <sys/uio.h> 53210312Sjmallett 54210312Sjmallett#include <opencrypto/cryptodev.h> 55210312Sjmallett 56210312Sjmallett#include <contrib/octeon-sdk/cvmx.h> 57210312Sjmallett 58210312Sjmallett#include <mips/cavium/cryptocteon/cryptocteonvar.h> 59210312Sjmallett 60210312Sjmallett/****************************************************************************/ 61210312Sjmallett 62210312Sjmallett#define IOV_INIT(iov, ptr, idx, len) \ 63210312Sjmallett do { \ 64210312Sjmallett (idx) = 0; \ 65210312Sjmallett (ptr) = (iov)[(idx)].iov_base; \ 66210312Sjmallett (len) = (iov)[(idx)].iov_len; \ 67210312Sjmallett } while (0) 68210312Sjmallett 69210312Sjmallett/* 70210312Sjmallett * XXX 71210312Sjmallett * It would be better if this were an IOV_READ/IOV_WRITE macro instead so 72210312Sjmallett * that we could detect overflow before it happens rather than right after, 73210312Sjmallett * which is especially bad since there is usually no IOV_CONSUME after the 74210312Sjmallett * final read or write. 75210312Sjmallett */ 76210312Sjmallett#define IOV_CONSUME(iov, ptr, idx, len) \ 77210312Sjmallett do { \ 78210312Sjmallett if ((len) > sizeof *(ptr)) { \ 79210312Sjmallett (len) -= sizeof *(ptr); \ 80210312Sjmallett (ptr)++; \ 81210312Sjmallett } else { \ 82210312Sjmallett if ((len) != sizeof *(ptr)) \ 83210312Sjmallett panic("%s: went past end of iovec.", __func__); \ 84210312Sjmallett (idx)++; \ 85210312Sjmallett (ptr) = (iov)[(idx)].iov_base; \ 86210312Sjmallett (len) = (iov)[(idx)].iov_len; \ 87210312Sjmallett } \ 88210312Sjmallett } while (0) 89210312Sjmallett 90210312Sjmallett#define ESP_HEADER_LENGTH 8 91210312Sjmallett#define DES_CBC_IV_LENGTH 8 92210312Sjmallett#define AES_CBC_IV_LENGTH 16 93210312Sjmallett#define ESP_HMAC_LEN 12 94210312Sjmallett 95210312Sjmallett#define ESP_HEADER_LENGTH 8 96210312Sjmallett#define DES_CBC_IV_LENGTH 8 97210312Sjmallett 98210312Sjmallett/****************************************************************************/ 99210312Sjmallett 100210312Sjmallett#define CVM_LOAD_SHA_UNIT(dat, next) { \ 101210312Sjmallett if (next == 0) { \ 102210312Sjmallett next = 1; \ 103210312Sjmallett CVMX_MT_HSH_DAT (dat, 0); \ 104210312Sjmallett } else if (next == 1) { \ 105210312Sjmallett next = 2; \ 106210312Sjmallett CVMX_MT_HSH_DAT (dat, 1); \ 107210312Sjmallett } else if (next == 2) { \ 108210312Sjmallett next = 3; \ 109210312Sjmallett CVMX_MT_HSH_DAT (dat, 2); \ 110210312Sjmallett } else if (next == 3) { \ 111210312Sjmallett next = 4; \ 112210312Sjmallett CVMX_MT_HSH_DAT (dat, 3); \ 113210312Sjmallett } else if (next == 4) { \ 114210312Sjmallett next = 5; \ 115210312Sjmallett CVMX_MT_HSH_DAT (dat, 4); \ 116210312Sjmallett } else if (next == 5) { \ 117210312Sjmallett next = 6; \ 118210312Sjmallett CVMX_MT_HSH_DAT (dat, 5); \ 119210312Sjmallett } else if (next == 6) { \ 120210312Sjmallett next = 7; \ 121210312Sjmallett CVMX_MT_HSH_DAT (dat, 6); \ 122210312Sjmallett } else { \ 123210312Sjmallett CVMX_MT_HSH_STARTSHA (dat); \ 124210312Sjmallett next = 0; \ 125210312Sjmallett } \ 126210312Sjmallett} 127210312Sjmallett 128210312Sjmallett#define CVM_LOAD2_SHA_UNIT(dat1, dat2, next) { \ 129210312Sjmallett if (next == 0) { \ 130210312Sjmallett CVMX_MT_HSH_DAT (dat1, 0); \ 131210312Sjmallett CVMX_MT_HSH_DAT (dat2, 1); \ 132210312Sjmallett next = 2; \ 133210312Sjmallett } else if (next == 1) { \ 134210312Sjmallett CVMX_MT_HSH_DAT (dat1, 1); \ 135210312Sjmallett CVMX_MT_HSH_DAT (dat2, 2); \ 136210312Sjmallett next = 3; \ 137210312Sjmallett } else if (next == 2) { \ 138210312Sjmallett CVMX_MT_HSH_DAT (dat1, 2); \ 139210312Sjmallett CVMX_MT_HSH_DAT (dat2, 3); \ 140210312Sjmallett next = 4; \ 141210312Sjmallett } else if (next == 3) { \ 142210312Sjmallett CVMX_MT_HSH_DAT (dat1, 3); \ 143210312Sjmallett CVMX_MT_HSH_DAT (dat2, 4); \ 144210312Sjmallett next = 5; \ 145210312Sjmallett } else if (next == 4) { \ 146210312Sjmallett CVMX_MT_HSH_DAT (dat1, 4); \ 147210312Sjmallett CVMX_MT_HSH_DAT (dat2, 5); \ 148210312Sjmallett next = 6; \ 149210312Sjmallett } else if (next == 5) { \ 150210312Sjmallett CVMX_MT_HSH_DAT (dat1, 5); \ 151210312Sjmallett CVMX_MT_HSH_DAT (dat2, 6); \ 152210312Sjmallett next = 7; \ 153210312Sjmallett } else if (next == 6) { \ 154210312Sjmallett CVMX_MT_HSH_DAT (dat1, 6); \ 155210312Sjmallett CVMX_MT_HSH_STARTSHA (dat2); \ 156210312Sjmallett next = 0; \ 157210312Sjmallett } else { \ 158210312Sjmallett CVMX_MT_HSH_STARTSHA (dat1); \ 159210312Sjmallett CVMX_MT_HSH_DAT (dat2, 0); \ 160210312Sjmallett next = 1; \ 161210312Sjmallett } \ 162210312Sjmallett} 163210312Sjmallett 164210312Sjmallett/****************************************************************************/ 165210312Sjmallett 166210312Sjmallett#define CVM_LOAD_MD5_UNIT(dat, next) { \ 167210312Sjmallett if (next == 0) { \ 168210312Sjmallett next = 1; \ 169210312Sjmallett CVMX_MT_HSH_DAT (dat, 0); \ 170210312Sjmallett } else if (next == 1) { \ 171210312Sjmallett next = 2; \ 172210312Sjmallett CVMX_MT_HSH_DAT (dat, 1); \ 173210312Sjmallett } else if (next == 2) { \ 174210312Sjmallett next = 3; \ 175210312Sjmallett CVMX_MT_HSH_DAT (dat, 2); \ 176210312Sjmallett } else if (next == 3) { \ 177210312Sjmallett next = 4; \ 178210312Sjmallett CVMX_MT_HSH_DAT (dat, 3); \ 179210312Sjmallett } else if (next == 4) { \ 180210312Sjmallett next = 5; \ 181210312Sjmallett CVMX_MT_HSH_DAT (dat, 4); \ 182210312Sjmallett } else if (next == 5) { \ 183210312Sjmallett next = 6; \ 184210312Sjmallett CVMX_MT_HSH_DAT (dat, 5); \ 185210312Sjmallett } else if (next == 6) { \ 186210312Sjmallett next = 7; \ 187210312Sjmallett CVMX_MT_HSH_DAT (dat, 6); \ 188210312Sjmallett } else { \ 189210312Sjmallett CVMX_MT_HSH_STARTMD5 (dat); \ 190210312Sjmallett next = 0; \ 191210312Sjmallett } \ 192210312Sjmallett} 193210312Sjmallett 194210312Sjmallett#define CVM_LOAD2_MD5_UNIT(dat1, dat2, next) { \ 195210312Sjmallett if (next == 0) { \ 196210312Sjmallett CVMX_MT_HSH_DAT (dat1, 0); \ 197210312Sjmallett CVMX_MT_HSH_DAT (dat2, 1); \ 198210312Sjmallett next = 2; \ 199210312Sjmallett } else if (next == 1) { \ 200210312Sjmallett CVMX_MT_HSH_DAT (dat1, 1); \ 201210312Sjmallett CVMX_MT_HSH_DAT (dat2, 2); \ 202210312Sjmallett next = 3; \ 203210312Sjmallett } else if (next == 2) { \ 204210312Sjmallett CVMX_MT_HSH_DAT (dat1, 2); \ 205210312Sjmallett CVMX_MT_HSH_DAT (dat2, 3); \ 206210312Sjmallett next = 4; \ 207210312Sjmallett } else if (next == 3) { \ 208210312Sjmallett CVMX_MT_HSH_DAT (dat1, 3); \ 209210312Sjmallett CVMX_MT_HSH_DAT (dat2, 4); \ 210210312Sjmallett next = 5; \ 211210312Sjmallett } else if (next == 4) { \ 212210312Sjmallett CVMX_MT_HSH_DAT (dat1, 4); \ 213210312Sjmallett CVMX_MT_HSH_DAT (dat2, 5); \ 214210312Sjmallett next = 6; \ 215210312Sjmallett } else if (next == 5) { \ 216210312Sjmallett CVMX_MT_HSH_DAT (dat1, 5); \ 217210312Sjmallett CVMX_MT_HSH_DAT (dat2, 6); \ 218210312Sjmallett next = 7; \ 219210312Sjmallett } else if (next == 6) { \ 220210312Sjmallett CVMX_MT_HSH_DAT (dat1, 6); \ 221210312Sjmallett CVMX_MT_HSH_STARTMD5 (dat2); \ 222210312Sjmallett next = 0; \ 223210312Sjmallett } else { \ 224210312Sjmallett CVMX_MT_HSH_STARTMD5 (dat1); \ 225210312Sjmallett CVMX_MT_HSH_DAT (dat2, 0); \ 226210312Sjmallett next = 1; \ 227210312Sjmallett } \ 228210312Sjmallett} 229210312Sjmallett 230210312Sjmallett/****************************************************************************/ 231210312Sjmallett 232210312Sjmallettvoid 233210312Sjmallettocto_calc_hash(uint8_t auth, unsigned char *key, uint64_t *inner, uint64_t *outer) 234210312Sjmallett{ 235210312Sjmallett uint8_t hash_key[64]; 236210312Sjmallett uint64_t *key1; 237210312Sjmallett register uint64_t xor1 = 0x3636363636363636ULL; 238210312Sjmallett register uint64_t xor2 = 0x5c5c5c5c5c5c5c5cULL; 239210312Sjmallett 240210312Sjmallett dprintf("%s()\n", __func__); 241210312Sjmallett 242210312Sjmallett memset(hash_key, 0, sizeof(hash_key)); 243210312Sjmallett memcpy(hash_key, (uint8_t *) key, (auth ? 20 : 16)); 244210312Sjmallett key1 = (uint64_t *) hash_key; 245210312Sjmallett if (auth) { 246210312Sjmallett CVMX_MT_HSH_IV(0x67452301EFCDAB89ULL, 0); 247210312Sjmallett CVMX_MT_HSH_IV(0x98BADCFE10325476ULL, 1); 248210312Sjmallett CVMX_MT_HSH_IV(0xC3D2E1F000000000ULL, 2); 249210312Sjmallett } else { 250210312Sjmallett CVMX_MT_HSH_IV(0x0123456789ABCDEFULL, 0); 251210312Sjmallett CVMX_MT_HSH_IV(0xFEDCBA9876543210ULL, 1); 252210312Sjmallett } 253210312Sjmallett 254210312Sjmallett CVMX_MT_HSH_DAT((*key1 ^ xor1), 0); 255210312Sjmallett key1++; 256210312Sjmallett CVMX_MT_HSH_DAT((*key1 ^ xor1), 1); 257210312Sjmallett key1++; 258210312Sjmallett CVMX_MT_HSH_DAT((*key1 ^ xor1), 2); 259210312Sjmallett key1++; 260210312Sjmallett CVMX_MT_HSH_DAT((*key1 ^ xor1), 3); 261210312Sjmallett key1++; 262210312Sjmallett CVMX_MT_HSH_DAT((*key1 ^ xor1), 4); 263210312Sjmallett key1++; 264210312Sjmallett CVMX_MT_HSH_DAT((*key1 ^ xor1), 5); 265210312Sjmallett key1++; 266210312Sjmallett CVMX_MT_HSH_DAT((*key1 ^ xor1), 6); 267210312Sjmallett key1++; 268210312Sjmallett if (auth) 269210312Sjmallett CVMX_MT_HSH_STARTSHA((*key1 ^ xor1)); 270210312Sjmallett else 271210312Sjmallett CVMX_MT_HSH_STARTMD5((*key1 ^ xor1)); 272210312Sjmallett 273210312Sjmallett CVMX_MF_HSH_IV(inner[0], 0); 274210312Sjmallett CVMX_MF_HSH_IV(inner[1], 1); 275210312Sjmallett if (auth) { 276210312Sjmallett inner[2] = 0; 277210312Sjmallett CVMX_MF_HSH_IV(((uint64_t *) inner)[2], 2); 278210312Sjmallett } 279210312Sjmallett 280210312Sjmallett memset(hash_key, 0, sizeof(hash_key)); 281210312Sjmallett memcpy(hash_key, (uint8_t *) key, (auth ? 20 : 16)); 282210312Sjmallett key1 = (uint64_t *) hash_key; 283210312Sjmallett if (auth) { 284210312Sjmallett CVMX_MT_HSH_IV(0x67452301EFCDAB89ULL, 0); 285210312Sjmallett CVMX_MT_HSH_IV(0x98BADCFE10325476ULL, 1); 286210312Sjmallett CVMX_MT_HSH_IV(0xC3D2E1F000000000ULL, 2); 287210312Sjmallett } else { 288210312Sjmallett CVMX_MT_HSH_IV(0x0123456789ABCDEFULL, 0); 289210312Sjmallett CVMX_MT_HSH_IV(0xFEDCBA9876543210ULL, 1); 290210312Sjmallett } 291210312Sjmallett 292210312Sjmallett CVMX_MT_HSH_DAT((*key1 ^ xor2), 0); 293210312Sjmallett key1++; 294210312Sjmallett CVMX_MT_HSH_DAT((*key1 ^ xor2), 1); 295210312Sjmallett key1++; 296210312Sjmallett CVMX_MT_HSH_DAT((*key1 ^ xor2), 2); 297210312Sjmallett key1++; 298210312Sjmallett CVMX_MT_HSH_DAT((*key1 ^ xor2), 3); 299210312Sjmallett key1++; 300210312Sjmallett CVMX_MT_HSH_DAT((*key1 ^ xor2), 4); 301210312Sjmallett key1++; 302210312Sjmallett CVMX_MT_HSH_DAT((*key1 ^ xor2), 5); 303210312Sjmallett key1++; 304210312Sjmallett CVMX_MT_HSH_DAT((*key1 ^ xor2), 6); 305210312Sjmallett key1++; 306210312Sjmallett if (auth) 307210312Sjmallett CVMX_MT_HSH_STARTSHA((*key1 ^ xor2)); 308210312Sjmallett else 309210312Sjmallett CVMX_MT_HSH_STARTMD5((*key1 ^ xor2)); 310210312Sjmallett 311210312Sjmallett CVMX_MF_HSH_IV(outer[0], 0); 312210312Sjmallett CVMX_MF_HSH_IV(outer[1], 1); 313210312Sjmallett if (auth) { 314210312Sjmallett outer[2] = 0; 315210312Sjmallett CVMX_MF_HSH_IV(outer[2], 2); 316210312Sjmallett } 317210312Sjmallett return; 318210312Sjmallett} 319210312Sjmallett 320210312Sjmallett/****************************************************************************/ 321210312Sjmallett/* DES functions */ 322210312Sjmallett 323210312Sjmallettint 324210312Sjmallettocto_des_cbc_encrypt( 325210312Sjmallett struct octo_sess *od, 326210312Sjmallett struct iovec *iov, size_t iovcnt, size_t iovlen, 327210312Sjmallett int auth_off, int auth_len, 328210312Sjmallett int crypt_off, int crypt_len, 329210312Sjmallett int icv_off, uint8_t *ivp) 330210312Sjmallett{ 331210312Sjmallett uint64_t *data; 332210312Sjmallett int data_i, data_l; 333210312Sjmallett 334210312Sjmallett dprintf("%s()\n", __func__); 335210312Sjmallett 336210312Sjmallett if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL || 337210312Sjmallett (crypt_off & 0x7) || (crypt_off + crypt_len > iovlen))) { 338217620Sgonzo dprintf("%s: Bad parameters od=%p iov=%p iovlen=%jd " 339210312Sjmallett "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d " 340210312Sjmallett "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen, 341210312Sjmallett auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp); 342210312Sjmallett return -EINVAL; 343210312Sjmallett } 344210312Sjmallett 345210312Sjmallett IOV_INIT(iov, data, data_i, data_l); 346210312Sjmallett 347210312Sjmallett CVMX_PREFETCH0(ivp); 348210312Sjmallett CVMX_PREFETCH0(od->octo_enckey); 349210312Sjmallett 350210312Sjmallett 351210312Sjmallett /* load 3DES Key */ 352210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0); 353210312Sjmallett if (od->octo_encklen == 24) { 354210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1); 355210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2); 356210312Sjmallett } else if (od->octo_encklen == 8) { 357210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1); 358210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2); 359210312Sjmallett } else { 360210312Sjmallett dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen); 361210312Sjmallett return -EINVAL; 362210312Sjmallett } 363210312Sjmallett 364210312Sjmallett CVMX_MT_3DES_IV(* (uint64_t *) ivp); 365210312Sjmallett 366210312Sjmallett while (crypt_off > 0) { 367210312Sjmallett IOV_CONSUME(iov, data, data_i, data_l); 368210312Sjmallett crypt_off -= 8; 369210312Sjmallett } 370210312Sjmallett 371210312Sjmallett while (crypt_len > 0) { 372210312Sjmallett CVMX_MT_3DES_ENC_CBC(*data); 373210312Sjmallett CVMX_MF_3DES_RESULT(*data); 374210312Sjmallett IOV_CONSUME(iov, data, data_i, data_l); 375210312Sjmallett crypt_len -= 8; 376210312Sjmallett } 377210312Sjmallett 378210312Sjmallett return 0; 379210312Sjmallett} 380210312Sjmallett 381210312Sjmallett 382210312Sjmallettint 383210312Sjmallettocto_des_cbc_decrypt( 384210312Sjmallett struct octo_sess *od, 385210312Sjmallett struct iovec *iov, size_t iovcnt, size_t iovlen, 386210312Sjmallett int auth_off, int auth_len, 387210312Sjmallett int crypt_off, int crypt_len, 388210312Sjmallett int icv_off, uint8_t *ivp) 389210312Sjmallett{ 390210312Sjmallett uint64_t *data; 391210312Sjmallett int data_i, data_l; 392210312Sjmallett 393210312Sjmallett dprintf("%s()\n", __func__); 394210312Sjmallett 395210312Sjmallett if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL || 396210312Sjmallett (crypt_off & 0x7) || (crypt_off + crypt_len > iovlen))) { 397217620Sgonzo dprintf("%s: Bad parameters od=%p iov=%p iovlen=%jd " 398210312Sjmallett "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d " 399210312Sjmallett "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen, 400210312Sjmallett auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp); 401210312Sjmallett return -EINVAL; 402210312Sjmallett } 403210312Sjmallett 404210312Sjmallett IOV_INIT(iov, data, data_i, data_l); 405210312Sjmallett 406210312Sjmallett CVMX_PREFETCH0(ivp); 407210312Sjmallett CVMX_PREFETCH0(od->octo_enckey); 408210312Sjmallett 409210312Sjmallett /* load 3DES Key */ 410210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0); 411210312Sjmallett if (od->octo_encklen == 24) { 412210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1); 413210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2); 414210312Sjmallett } else if (od->octo_encklen == 8) { 415210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1); 416210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2); 417210312Sjmallett } else { 418210312Sjmallett dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen); 419210312Sjmallett return -EINVAL; 420210312Sjmallett } 421210312Sjmallett 422210312Sjmallett CVMX_MT_3DES_IV(* (uint64_t *) ivp); 423210312Sjmallett 424210312Sjmallett while (crypt_off > 0) { 425210312Sjmallett IOV_CONSUME(iov, data, data_i, data_l); 426210312Sjmallett crypt_off -= 8; 427210312Sjmallett } 428210312Sjmallett 429210312Sjmallett while (crypt_len > 0) { 430210312Sjmallett CVMX_MT_3DES_DEC_CBC(*data); 431210312Sjmallett CVMX_MF_3DES_RESULT(*data); 432210312Sjmallett IOV_CONSUME(iov, data, data_i, data_l); 433210312Sjmallett crypt_len -= 8; 434210312Sjmallett } 435210312Sjmallett 436210312Sjmallett return 0; 437210312Sjmallett} 438210312Sjmallett 439210312Sjmallett/****************************************************************************/ 440210312Sjmallett/* AES functions */ 441210312Sjmallett 442210312Sjmallettint 443210312Sjmallettocto_aes_cbc_encrypt( 444210312Sjmallett struct octo_sess *od, 445210312Sjmallett struct iovec *iov, size_t iovcnt, size_t iovlen, 446210312Sjmallett int auth_off, int auth_len, 447210312Sjmallett int crypt_off, int crypt_len, 448210312Sjmallett int icv_off, uint8_t *ivp) 449210312Sjmallett{ 450210312Sjmallett uint64_t *data, *pdata; 451210312Sjmallett int data_i, data_l; 452210312Sjmallett 453210312Sjmallett dprintf("%s()\n", __func__); 454210312Sjmallett 455210312Sjmallett if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL || 456210312Sjmallett (crypt_off & 0x7) || (crypt_off + crypt_len > iovlen))) { 457217620Sgonzo dprintf("%s: Bad parameters od=%p iov=%p iovlen=%jd " 458210312Sjmallett "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d " 459210312Sjmallett "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen, 460210312Sjmallett auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp); 461210312Sjmallett return -EINVAL; 462210312Sjmallett } 463210312Sjmallett 464210312Sjmallett IOV_INIT(iov, data, data_i, data_l); 465210312Sjmallett 466210312Sjmallett CVMX_PREFETCH0(ivp); 467210312Sjmallett CVMX_PREFETCH0(od->octo_enckey); 468210312Sjmallett 469210312Sjmallett /* load AES Key */ 470210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0); 471210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1); 472210312Sjmallett 473210312Sjmallett if (od->octo_encklen == 16) { 474210312Sjmallett CVMX_MT_AES_KEY(0x0, 2); 475210312Sjmallett CVMX_MT_AES_KEY(0x0, 3); 476210312Sjmallett } else if (od->octo_encklen == 24) { 477210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2); 478210312Sjmallett CVMX_MT_AES_KEY(0x0, 3); 479210312Sjmallett } else if (od->octo_encklen == 32) { 480210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2); 481210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3); 482210312Sjmallett } else { 483210312Sjmallett dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen); 484210312Sjmallett return -EINVAL; 485210312Sjmallett } 486210312Sjmallett CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1); 487210312Sjmallett 488210312Sjmallett CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0); 489210312Sjmallett CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1); 490210312Sjmallett 491210312Sjmallett while (crypt_off > 0) { 492210312Sjmallett IOV_CONSUME(iov, data, data_i, data_l); 493210312Sjmallett crypt_off -= 8; 494210312Sjmallett } 495210312Sjmallett 496210312Sjmallett while (crypt_len > 0) { 497210312Sjmallett pdata = data; 498210312Sjmallett CVMX_MT_AES_ENC_CBC0(*data); 499210312Sjmallett IOV_CONSUME(iov, data, data_i, data_l); 500210312Sjmallett CVMX_MT_AES_ENC_CBC1(*data); 501210312Sjmallett CVMX_MF_AES_RESULT(*pdata, 0); 502210312Sjmallett CVMX_MF_AES_RESULT(*data, 1); 503210312Sjmallett IOV_CONSUME(iov, data, data_i, data_l); 504210312Sjmallett crypt_len -= 16; 505210312Sjmallett } 506210312Sjmallett 507210312Sjmallett return 0; 508210312Sjmallett} 509210312Sjmallett 510210312Sjmallett 511210312Sjmallettint 512210312Sjmallettocto_aes_cbc_decrypt( 513210312Sjmallett struct octo_sess *od, 514210312Sjmallett struct iovec *iov, size_t iovcnt, size_t iovlen, 515210312Sjmallett int auth_off, int auth_len, 516210312Sjmallett int crypt_off, int crypt_len, 517210312Sjmallett int icv_off, uint8_t *ivp) 518210312Sjmallett{ 519210312Sjmallett uint64_t *data, *pdata; 520210312Sjmallett int data_i, data_l; 521210312Sjmallett 522210312Sjmallett dprintf("%s()\n", __func__); 523210312Sjmallett 524210312Sjmallett if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL || 525210312Sjmallett (crypt_off & 0x7) || (crypt_off + crypt_len > iovlen))) { 526217620Sgonzo dprintf("%s: Bad parameters od=%p iov=%p iovlen=%jd " 527210312Sjmallett "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d " 528210312Sjmallett "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen, 529210312Sjmallett auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp); 530210312Sjmallett return -EINVAL; 531210312Sjmallett } 532210312Sjmallett 533210312Sjmallett IOV_INIT(iov, data, data_i, data_l); 534210312Sjmallett 535210312Sjmallett CVMX_PREFETCH0(ivp); 536210312Sjmallett CVMX_PREFETCH0(od->octo_enckey); 537210312Sjmallett 538210312Sjmallett /* load AES Key */ 539210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0); 540210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1); 541210312Sjmallett 542210312Sjmallett if (od->octo_encklen == 16) { 543210312Sjmallett CVMX_MT_AES_KEY(0x0, 2); 544210312Sjmallett CVMX_MT_AES_KEY(0x0, 3); 545210312Sjmallett } else if (od->octo_encklen == 24) { 546210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2); 547210312Sjmallett CVMX_MT_AES_KEY(0x0, 3); 548210312Sjmallett } else if (od->octo_encklen == 32) { 549210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2); 550210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3); 551210312Sjmallett } else { 552210312Sjmallett dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen); 553210312Sjmallett return -EINVAL; 554210312Sjmallett } 555210312Sjmallett CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1); 556210312Sjmallett 557210312Sjmallett CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0); 558210312Sjmallett CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1); 559210312Sjmallett 560210312Sjmallett while (crypt_off > 0) { 561210312Sjmallett IOV_CONSUME(iov, data, data_i, data_l); 562210312Sjmallett crypt_off -= 8; 563210312Sjmallett } 564210312Sjmallett 565210312Sjmallett while (crypt_len > 0) { 566210312Sjmallett pdata = data; 567210312Sjmallett CVMX_MT_AES_DEC_CBC0(*data); 568210312Sjmallett IOV_CONSUME(iov, data, data_i, data_l); 569210312Sjmallett CVMX_MT_AES_DEC_CBC1(*data); 570210312Sjmallett CVMX_MF_AES_RESULT(*pdata, 0); 571210312Sjmallett CVMX_MF_AES_RESULT(*data, 1); 572210312Sjmallett IOV_CONSUME(iov, data, data_i, data_l); 573210312Sjmallett crypt_len -= 16; 574210312Sjmallett } 575210312Sjmallett 576210312Sjmallett return 0; 577210312Sjmallett} 578210312Sjmallett 579210312Sjmallett/****************************************************************************/ 580210312Sjmallett/* MD5 */ 581210312Sjmallett 582210312Sjmallettint 583210312Sjmallettocto_null_md5_encrypt( 584210312Sjmallett struct octo_sess *od, 585210312Sjmallett struct iovec *iov, size_t iovcnt, size_t iovlen, 586210312Sjmallett int auth_off, int auth_len, 587210312Sjmallett int crypt_off, int crypt_len, 588210312Sjmallett int icv_off, uint8_t *ivp) 589210312Sjmallett{ 590210312Sjmallett register int next = 0; 591210312Sjmallett uint64_t *data; 592210312Sjmallett uint64_t tmp1, tmp2; 593210312Sjmallett int data_i, data_l, alen = auth_len; 594210312Sjmallett 595210312Sjmallett dprintf("%s()\n", __func__); 596210312Sjmallett 597210312Sjmallett if (__predict_false(od == NULL || iov==NULL || iovlen==0 || 598210312Sjmallett (auth_off & 0x7) || (auth_off + auth_len > iovlen))) { 599217620Sgonzo dprintf("%s: Bad parameters od=%p iov=%p iovlen=%jd " 600210312Sjmallett "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d " 601210312Sjmallett "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen, 602210312Sjmallett auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp); 603210312Sjmallett return -EINVAL; 604210312Sjmallett } 605210312Sjmallett 606210312Sjmallett IOV_INIT(iov, data, data_i, data_l); 607210312Sjmallett 608210312Sjmallett /* Load MD5 IV */ 609210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[0], 0); 610210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[1], 1); 611210312Sjmallett 612210312Sjmallett while (auth_off > 0) { 613210312Sjmallett IOV_CONSUME(iov, data, data_i, data_l); 614210312Sjmallett auth_off -= 8; 615210312Sjmallett } 616210312Sjmallett 617210312Sjmallett while (auth_len > 0) { 618210312Sjmallett CVM_LOAD_MD5_UNIT(*data, next); 619210312Sjmallett auth_len -= 8; 620210312Sjmallett IOV_CONSUME(iov, data, data_i, data_l); 621210312Sjmallett } 622210312Sjmallett 623210312Sjmallett /* finish the hash */ 624210312Sjmallett CVMX_PREFETCH0(od->octo_hmouter); 625210312Sjmallett#if 0 626210312Sjmallett if (__predict_false(inplen)) { 627210312Sjmallett uint64_t tmp = 0; 628210312Sjmallett uint8_t *p = (uint8_t *) & tmp; 629210312Sjmallett p[inplen] = 0x80; 630210312Sjmallett do { 631210312Sjmallett inplen--; 632210312Sjmallett p[inplen] = ((uint8_t *) data)[inplen]; 633210312Sjmallett } while (inplen); 634210312Sjmallett CVM_LOAD_MD5_UNIT(tmp, next); 635210312Sjmallett } else { 636210312Sjmallett CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next); 637210312Sjmallett } 638210312Sjmallett#else 639210312Sjmallett CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next); 640210312Sjmallett#endif 641210312Sjmallett 642210312Sjmallett /* Finish Inner hash */ 643210312Sjmallett while (next != 7) { 644210312Sjmallett CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next); 645210312Sjmallett } 646210312Sjmallett CVMX_ES64(tmp1, ((alen + 64) << 3)); 647210312Sjmallett CVM_LOAD_MD5_UNIT(tmp1, next); 648210312Sjmallett 649210312Sjmallett /* Get the inner hash of HMAC */ 650210312Sjmallett CVMX_MF_HSH_IV(tmp1, 0); 651210312Sjmallett CVMX_MF_HSH_IV(tmp2, 1); 652210312Sjmallett 653210312Sjmallett /* Initialize hash unit */ 654210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[0], 0); 655210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[1], 1); 656210312Sjmallett 657210312Sjmallett CVMX_MT_HSH_DAT(tmp1, 0); 658210312Sjmallett CVMX_MT_HSH_DAT(tmp2, 1); 659210312Sjmallett CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2); 660210312Sjmallett CVMX_MT_HSH_DATZ(3); 661210312Sjmallett CVMX_MT_HSH_DATZ(4); 662210312Sjmallett CVMX_MT_HSH_DATZ(5); 663210312Sjmallett CVMX_MT_HSH_DATZ(6); 664210312Sjmallett CVMX_ES64(tmp1, ((64 + 16) << 3)); 665210312Sjmallett CVMX_MT_HSH_STARTMD5(tmp1); 666210312Sjmallett 667210312Sjmallett /* save the HMAC */ 668210312Sjmallett IOV_INIT(iov, data, data_i, data_l); 669210312Sjmallett while (icv_off > 0) { 670210312Sjmallett IOV_CONSUME(iov, data, data_i, data_l); 671210312Sjmallett icv_off -= 8; 672210312Sjmallett } 673210312Sjmallett CVMX_MF_HSH_IV(*data, 0); 674210312Sjmallett IOV_CONSUME(iov, data, data_i, data_l); 675210312Sjmallett CVMX_MF_HSH_IV(tmp1, 1); 676210312Sjmallett *(uint32_t *)data = (uint32_t) (tmp1 >> 32); 677210312Sjmallett 678210312Sjmallett return 0; 679210312Sjmallett} 680210312Sjmallett 681210312Sjmallett/****************************************************************************/ 682210312Sjmallett/* SHA1 */ 683210312Sjmallett 684210312Sjmallettint 685210312Sjmallettocto_null_sha1_encrypt( 686210312Sjmallett struct octo_sess *od, 687210312Sjmallett struct iovec *iov, size_t iovcnt, size_t iovlen, 688210312Sjmallett int auth_off, int auth_len, 689210312Sjmallett int crypt_off, int crypt_len, 690210312Sjmallett int icv_off, uint8_t *ivp) 691210312Sjmallett{ 692210312Sjmallett register int next = 0; 693210312Sjmallett uint64_t *data; 694210312Sjmallett uint64_t tmp1, tmp2, tmp3; 695210312Sjmallett int data_i, data_l, alen = auth_len; 696210312Sjmallett 697210312Sjmallett dprintf("%s()\n", __func__); 698210312Sjmallett 699210312Sjmallett if (__predict_false(od == NULL || iov==NULL || iovlen==0 || 700210312Sjmallett (auth_off & 0x7) || (auth_off + auth_len > iovlen))) { 701217620Sgonzo dprintf("%s: Bad parameters od=%p iov=%p iovlen=%jd " 702210312Sjmallett "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d " 703210312Sjmallett "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen, 704210312Sjmallett auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp); 705210312Sjmallett return -EINVAL; 706210312Sjmallett } 707210312Sjmallett 708210312Sjmallett IOV_INIT(iov, data, data_i, data_l); 709210312Sjmallett 710210312Sjmallett /* Load SHA1 IV */ 711210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[0], 0); 712210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[1], 1); 713210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[2], 2); 714210312Sjmallett 715210312Sjmallett while (auth_off > 0) { 716210312Sjmallett IOV_CONSUME(iov, data, data_i, data_l); 717210312Sjmallett auth_off -= 8; 718210312Sjmallett } 719210312Sjmallett 720210312Sjmallett while (auth_len > 0) { 721210312Sjmallett CVM_LOAD_SHA_UNIT(*data, next); 722210312Sjmallett auth_len -= 8; 723210312Sjmallett IOV_CONSUME(iov, data, data_i, data_l); 724210312Sjmallett } 725210312Sjmallett 726210312Sjmallett /* finish the hash */ 727210312Sjmallett CVMX_PREFETCH0(od->octo_hmouter); 728210312Sjmallett#if 0 729210312Sjmallett if (__predict_false(inplen)) { 730210312Sjmallett uint64_t tmp = 0; 731210312Sjmallett uint8_t *p = (uint8_t *) & tmp; 732210312Sjmallett p[inplen] = 0x80; 733210312Sjmallett do { 734210312Sjmallett inplen--; 735210312Sjmallett p[inplen] = ((uint8_t *) data)[inplen]; 736210312Sjmallett } while (inplen); 737210312Sjmallett CVM_LOAD_MD5_UNIT(tmp, next); 738210312Sjmallett } else { 739210312Sjmallett CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next); 740210312Sjmallett } 741210312Sjmallett#else 742210312Sjmallett CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next); 743210312Sjmallett#endif 744210312Sjmallett 745210312Sjmallett /* Finish Inner hash */ 746210312Sjmallett while (next != 7) { 747210312Sjmallett CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next); 748210312Sjmallett } 749210312Sjmallett CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next); 750210312Sjmallett 751210312Sjmallett /* Get the inner hash of HMAC */ 752210312Sjmallett CVMX_MF_HSH_IV(tmp1, 0); 753210312Sjmallett CVMX_MF_HSH_IV(tmp2, 1); 754210312Sjmallett tmp3 = 0; 755210312Sjmallett CVMX_MF_HSH_IV(tmp3, 2); 756210312Sjmallett 757210312Sjmallett /* Initialize hash unit */ 758210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[0], 0); 759210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[1], 1); 760210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[2], 2); 761210312Sjmallett 762210312Sjmallett CVMX_MT_HSH_DAT(tmp1, 0); 763210312Sjmallett CVMX_MT_HSH_DAT(tmp2, 1); 764210312Sjmallett tmp3 |= 0x0000000080000000; 765210312Sjmallett CVMX_MT_HSH_DAT(tmp3, 2); 766210312Sjmallett CVMX_MT_HSH_DATZ(3); 767210312Sjmallett CVMX_MT_HSH_DATZ(4); 768210312Sjmallett CVMX_MT_HSH_DATZ(5); 769210312Sjmallett CVMX_MT_HSH_DATZ(6); 770210312Sjmallett CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3)); 771210312Sjmallett 772210312Sjmallett /* save the HMAC */ 773210312Sjmallett IOV_INIT(iov, data, data_i, data_l); 774210312Sjmallett while (icv_off > 0) { 775210312Sjmallett IOV_CONSUME(iov, data, data_i, data_l); 776210312Sjmallett icv_off -= 8; 777210312Sjmallett } 778210312Sjmallett CVMX_MF_HSH_IV(*data, 0); 779210312Sjmallett IOV_CONSUME(iov, data, data_i, data_l); 780210312Sjmallett CVMX_MF_HSH_IV(tmp1, 1); 781210312Sjmallett *(uint32_t *)data = (uint32_t) (tmp1 >> 32); 782210312Sjmallett 783210312Sjmallett return 0; 784210312Sjmallett} 785210312Sjmallett 786210312Sjmallett/****************************************************************************/ 787210312Sjmallett/* DES MD5 */ 788210312Sjmallett 789210312Sjmallettint 790210312Sjmallettocto_des_cbc_md5_encrypt( 791210312Sjmallett struct octo_sess *od, 792210312Sjmallett struct iovec *iov, size_t iovcnt, size_t iovlen, 793210312Sjmallett int auth_off, int auth_len, 794210312Sjmallett int crypt_off, int crypt_len, 795210312Sjmallett int icv_off, uint8_t *ivp) 796210312Sjmallett{ 797210312Sjmallett register int next = 0; 798210312Sjmallett union { 799210312Sjmallett uint32_t data32[2]; 800210312Sjmallett uint64_t data64[1]; 801210312Sjmallett } mydata; 802210312Sjmallett uint64_t *data = &mydata.data64[0]; 803210312Sjmallett uint32_t *data32; 804210312Sjmallett uint64_t tmp1, tmp2; 805210312Sjmallett int data_i, data_l, alen = auth_len; 806210312Sjmallett 807210312Sjmallett dprintf("%s()\n", __func__); 808210312Sjmallett 809210312Sjmallett if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL || 810210312Sjmallett (crypt_off & 0x3) || (crypt_off + crypt_len > iovlen) || 811210312Sjmallett (crypt_len & 0x7) || 812210312Sjmallett (auth_len & 0x7) || 813210312Sjmallett (auth_off & 0x3) || (auth_off + auth_len > iovlen))) { 814217620Sgonzo dprintf("%s: Bad parameters od=%p iov=%p iovlen=%jd " 815210312Sjmallett "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d " 816210312Sjmallett "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen, 817210312Sjmallett auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp); 818210312Sjmallett return -EINVAL; 819210312Sjmallett } 820210312Sjmallett 821210312Sjmallett IOV_INIT(iov, data32, data_i, data_l); 822210312Sjmallett 823210312Sjmallett CVMX_PREFETCH0(ivp); 824210312Sjmallett CVMX_PREFETCH0(od->octo_enckey); 825210312Sjmallett 826210312Sjmallett /* load 3DES Key */ 827210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0); 828210312Sjmallett if (od->octo_encklen == 24) { 829210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1); 830210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2); 831210312Sjmallett } else if (od->octo_encklen == 8) { 832210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1); 833210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2); 834210312Sjmallett } else { 835210312Sjmallett dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen); 836210312Sjmallett return -EINVAL; 837210312Sjmallett } 838210312Sjmallett 839210312Sjmallett CVMX_MT_3DES_IV(* (uint64_t *) ivp); 840210312Sjmallett 841210312Sjmallett /* Load MD5 IV */ 842210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[0], 0); 843210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[1], 1); 844210312Sjmallett 845210312Sjmallett while (crypt_off > 0 && auth_off > 0) { 846210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 847210312Sjmallett crypt_off -= 4; 848210312Sjmallett auth_off -= 4; 849210312Sjmallett } 850210312Sjmallett 851210312Sjmallett while (crypt_len > 0 || auth_len > 0) { 852210312Sjmallett uint32_t *first = data32; 853210312Sjmallett mydata.data32[0] = *first; 854210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 855210312Sjmallett mydata.data32[1] = *data32; 856210312Sjmallett if (crypt_off <= 0) { 857210312Sjmallett if (crypt_len > 0) { 858210312Sjmallett CVMX_MT_3DES_ENC_CBC(*data); 859210312Sjmallett CVMX_MF_3DES_RESULT(*data); 860210312Sjmallett crypt_len -= 8; 861210312Sjmallett } 862210312Sjmallett } else 863210312Sjmallett crypt_off -= 8; 864210312Sjmallett if (auth_off <= 0) { 865210312Sjmallett if (auth_len > 0) { 866210312Sjmallett CVM_LOAD_MD5_UNIT(*data, next); 867210312Sjmallett auth_len -= 8; 868210312Sjmallett } 869210312Sjmallett } else 870210312Sjmallett auth_off -= 8; 871210312Sjmallett *first = mydata.data32[0]; 872210312Sjmallett *data32 = mydata.data32[1]; 873210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 874210312Sjmallett } 875210312Sjmallett 876210312Sjmallett /* finish the hash */ 877210312Sjmallett CVMX_PREFETCH0(od->octo_hmouter); 878210312Sjmallett#if 0 879210312Sjmallett if (__predict_false(inplen)) { 880210312Sjmallett uint64_t tmp = 0; 881210312Sjmallett uint8_t *p = (uint8_t *) & tmp; 882210312Sjmallett p[inplen] = 0x80; 883210312Sjmallett do { 884210312Sjmallett inplen--; 885210312Sjmallett p[inplen] = ((uint8_t *) data)[inplen]; 886210312Sjmallett } while (inplen); 887210312Sjmallett CVM_LOAD_MD5_UNIT(tmp, next); 888210312Sjmallett } else { 889210312Sjmallett CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next); 890210312Sjmallett } 891210312Sjmallett#else 892210312Sjmallett CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next); 893210312Sjmallett#endif 894210312Sjmallett 895210312Sjmallett /* Finish Inner hash */ 896210312Sjmallett while (next != 7) { 897210312Sjmallett CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next); 898210312Sjmallett } 899210312Sjmallett CVMX_ES64(tmp1, ((alen + 64) << 3)); 900210312Sjmallett CVM_LOAD_MD5_UNIT(tmp1, next); 901210312Sjmallett 902210312Sjmallett /* Get the inner hash of HMAC */ 903210312Sjmallett CVMX_MF_HSH_IV(tmp1, 0); 904210312Sjmallett CVMX_MF_HSH_IV(tmp2, 1); 905210312Sjmallett 906210312Sjmallett /* Initialize hash unit */ 907210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[0], 0); 908210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[1], 1); 909210312Sjmallett 910210312Sjmallett CVMX_MT_HSH_DAT(tmp1, 0); 911210312Sjmallett CVMX_MT_HSH_DAT(tmp2, 1); 912210312Sjmallett CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2); 913210312Sjmallett CVMX_MT_HSH_DATZ(3); 914210312Sjmallett CVMX_MT_HSH_DATZ(4); 915210312Sjmallett CVMX_MT_HSH_DATZ(5); 916210312Sjmallett CVMX_MT_HSH_DATZ(6); 917210312Sjmallett CVMX_ES64(tmp1, ((64 + 16) << 3)); 918210312Sjmallett CVMX_MT_HSH_STARTMD5(tmp1); 919210312Sjmallett 920210312Sjmallett /* save the HMAC */ 921210312Sjmallett IOV_INIT(iov, data32, data_i, data_l); 922210312Sjmallett while (icv_off > 0) { 923210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 924210312Sjmallett icv_off -= 4; 925210312Sjmallett } 926210312Sjmallett CVMX_MF_HSH_IV(tmp1, 0); 927210312Sjmallett *data32 = (uint32_t) (tmp1 >> 32); 928210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 929210312Sjmallett *data32 = (uint32_t) tmp1; 930210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 931210312Sjmallett CVMX_MF_HSH_IV(tmp1, 1); 932210312Sjmallett *data32 = (uint32_t) (tmp1 >> 32); 933210312Sjmallett 934210312Sjmallett return 0; 935210312Sjmallett} 936210312Sjmallett 937210312Sjmallettint 938210312Sjmallettocto_des_cbc_md5_decrypt( 939210312Sjmallett struct octo_sess *od, 940210312Sjmallett struct iovec *iov, size_t iovcnt, size_t iovlen, 941210312Sjmallett int auth_off, int auth_len, 942210312Sjmallett int crypt_off, int crypt_len, 943210312Sjmallett int icv_off, uint8_t *ivp) 944210312Sjmallett{ 945210312Sjmallett register int next = 0; 946210312Sjmallett union { 947210312Sjmallett uint32_t data32[2]; 948210312Sjmallett uint64_t data64[1]; 949210312Sjmallett } mydata; 950210312Sjmallett uint64_t *data = &mydata.data64[0]; 951210312Sjmallett uint32_t *data32; 952210312Sjmallett uint64_t tmp1, tmp2; 953210312Sjmallett int data_i, data_l, alen = auth_len; 954210312Sjmallett 955210312Sjmallett dprintf("%s()\n", __func__); 956210312Sjmallett 957210312Sjmallett if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL || 958210312Sjmallett (crypt_off & 0x3) || (crypt_off + crypt_len > iovlen) || 959210312Sjmallett (crypt_len & 0x7) || 960210312Sjmallett (auth_len & 0x7) || 961210312Sjmallett (auth_off & 0x3) || (auth_off + auth_len > iovlen))) { 962217620Sgonzo dprintf("%s: Bad parameters od=%p iov=%p iovlen=%jd " 963210312Sjmallett "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d " 964210312Sjmallett "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen, 965210312Sjmallett auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp); 966210312Sjmallett return -EINVAL; 967210312Sjmallett } 968210312Sjmallett 969210312Sjmallett IOV_INIT(iov, data32, data_i, data_l); 970210312Sjmallett 971210312Sjmallett CVMX_PREFETCH0(ivp); 972210312Sjmallett CVMX_PREFETCH0(od->octo_enckey); 973210312Sjmallett 974210312Sjmallett /* load 3DES Key */ 975210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0); 976210312Sjmallett if (od->octo_encklen == 24) { 977210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1); 978210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2); 979210312Sjmallett } else if (od->octo_encklen == 8) { 980210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1); 981210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2); 982210312Sjmallett } else { 983210312Sjmallett dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen); 984210312Sjmallett return -EINVAL; 985210312Sjmallett } 986210312Sjmallett 987210312Sjmallett CVMX_MT_3DES_IV(* (uint64_t *) ivp); 988210312Sjmallett 989210312Sjmallett /* Load MD5 IV */ 990210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[0], 0); 991210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[1], 1); 992210312Sjmallett 993210312Sjmallett while (crypt_off > 0 && auth_off > 0) { 994210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 995210312Sjmallett crypt_off -= 4; 996210312Sjmallett auth_off -= 4; 997210312Sjmallett } 998210312Sjmallett 999210312Sjmallett while (crypt_len > 0 || auth_len > 0) { 1000210312Sjmallett uint32_t *first = data32; 1001210312Sjmallett mydata.data32[0] = *first; 1002210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1003210312Sjmallett mydata.data32[1] = *data32; 1004210312Sjmallett if (auth_off <= 0) { 1005210312Sjmallett if (auth_len > 0) { 1006210312Sjmallett CVM_LOAD_MD5_UNIT(*data, next); 1007210312Sjmallett auth_len -= 8; 1008210312Sjmallett } 1009210312Sjmallett } else 1010210312Sjmallett auth_off -= 8; 1011210312Sjmallett if (crypt_off <= 0) { 1012210312Sjmallett if (crypt_len > 0) { 1013210312Sjmallett CVMX_MT_3DES_DEC_CBC(*data); 1014210312Sjmallett CVMX_MF_3DES_RESULT(*data); 1015210312Sjmallett crypt_len -= 8; 1016210312Sjmallett } 1017210312Sjmallett } else 1018210312Sjmallett crypt_off -= 8; 1019210312Sjmallett *first = mydata.data32[0]; 1020210312Sjmallett *data32 = mydata.data32[1]; 1021210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1022210312Sjmallett } 1023210312Sjmallett 1024210312Sjmallett /* finish the hash */ 1025210312Sjmallett CVMX_PREFETCH0(od->octo_hmouter); 1026210312Sjmallett#if 0 1027210312Sjmallett if (__predict_false(inplen)) { 1028210312Sjmallett uint64_t tmp = 0; 1029210312Sjmallett uint8_t *p = (uint8_t *) & tmp; 1030210312Sjmallett p[inplen] = 0x80; 1031210312Sjmallett do { 1032210312Sjmallett inplen--; 1033210312Sjmallett p[inplen] = ((uint8_t *) data)[inplen]; 1034210312Sjmallett } while (inplen); 1035210312Sjmallett CVM_LOAD_MD5_UNIT(tmp, next); 1036210312Sjmallett } else { 1037210312Sjmallett CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next); 1038210312Sjmallett } 1039210312Sjmallett#else 1040210312Sjmallett CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next); 1041210312Sjmallett#endif 1042210312Sjmallett 1043210312Sjmallett /* Finish Inner hash */ 1044210312Sjmallett while (next != 7) { 1045210312Sjmallett CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next); 1046210312Sjmallett } 1047210312Sjmallett CVMX_ES64(tmp1, ((alen + 64) << 3)); 1048210312Sjmallett CVM_LOAD_MD5_UNIT(tmp1, next); 1049210312Sjmallett 1050210312Sjmallett /* Get the inner hash of HMAC */ 1051210312Sjmallett CVMX_MF_HSH_IV(tmp1, 0); 1052210312Sjmallett CVMX_MF_HSH_IV(tmp2, 1); 1053210312Sjmallett 1054210312Sjmallett /* Initialize hash unit */ 1055210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[0], 0); 1056210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[1], 1); 1057210312Sjmallett 1058210312Sjmallett CVMX_MT_HSH_DAT(tmp1, 0); 1059210312Sjmallett CVMX_MT_HSH_DAT(tmp2, 1); 1060210312Sjmallett CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2); 1061210312Sjmallett CVMX_MT_HSH_DATZ(3); 1062210312Sjmallett CVMX_MT_HSH_DATZ(4); 1063210312Sjmallett CVMX_MT_HSH_DATZ(5); 1064210312Sjmallett CVMX_MT_HSH_DATZ(6); 1065210312Sjmallett CVMX_ES64(tmp1, ((64 + 16) << 3)); 1066210312Sjmallett CVMX_MT_HSH_STARTMD5(tmp1); 1067210312Sjmallett 1068210312Sjmallett /* save the HMAC */ 1069210312Sjmallett IOV_INIT(iov, data32, data_i, data_l); 1070210312Sjmallett while (icv_off > 0) { 1071210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1072210312Sjmallett icv_off -= 4; 1073210312Sjmallett } 1074210312Sjmallett CVMX_MF_HSH_IV(tmp1, 0); 1075210312Sjmallett *data32 = (uint32_t) (tmp1 >> 32); 1076210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1077210312Sjmallett *data32 = (uint32_t) tmp1; 1078210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1079210312Sjmallett CVMX_MF_HSH_IV(tmp1, 1); 1080210312Sjmallett *data32 = (uint32_t) (tmp1 >> 32); 1081210312Sjmallett 1082210312Sjmallett return 0; 1083210312Sjmallett} 1084210312Sjmallett 1085210312Sjmallett/****************************************************************************/ 1086210312Sjmallett/* DES SHA */ 1087210312Sjmallett 1088210312Sjmallettint 1089210312Sjmallettocto_des_cbc_sha1_encrypt( 1090210312Sjmallett struct octo_sess *od, 1091210312Sjmallett struct iovec *iov, size_t iovcnt, size_t iovlen, 1092210312Sjmallett int auth_off, int auth_len, 1093210312Sjmallett int crypt_off, int crypt_len, 1094210312Sjmallett int icv_off, uint8_t *ivp) 1095210312Sjmallett{ 1096210312Sjmallett register int next = 0; 1097210312Sjmallett union { 1098210312Sjmallett uint32_t data32[2]; 1099210312Sjmallett uint64_t data64[1]; 1100210312Sjmallett } mydata; 1101210312Sjmallett uint64_t *data = &mydata.data64[0]; 1102210312Sjmallett uint32_t *data32; 1103210312Sjmallett uint64_t tmp1, tmp2, tmp3; 1104210312Sjmallett int data_i, data_l, alen = auth_len; 1105210312Sjmallett 1106210312Sjmallett dprintf("%s()\n", __func__); 1107210312Sjmallett 1108210312Sjmallett if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL || 1109210312Sjmallett (crypt_off & 0x3) || (crypt_off + crypt_len > iovlen) || 1110210312Sjmallett (crypt_len & 0x7) || 1111210312Sjmallett (auth_len & 0x7) || 1112210312Sjmallett (auth_off & 0x3) || (auth_off + auth_len > iovlen))) { 1113217620Sgonzo dprintf("%s: Bad parameters od=%p iov=%p iovlen=%jd " 1114210312Sjmallett "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d " 1115210312Sjmallett "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen, 1116210312Sjmallett auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp); 1117210312Sjmallett return -EINVAL; 1118210312Sjmallett } 1119210312Sjmallett 1120210312Sjmallett IOV_INIT(iov, data32, data_i, data_l); 1121210312Sjmallett 1122210312Sjmallett CVMX_PREFETCH0(ivp); 1123210312Sjmallett CVMX_PREFETCH0(od->octo_enckey); 1124210312Sjmallett 1125210312Sjmallett /* load 3DES Key */ 1126210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0); 1127210312Sjmallett if (od->octo_encklen == 24) { 1128210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1); 1129210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2); 1130210312Sjmallett } else if (od->octo_encklen == 8) { 1131210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1); 1132210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2); 1133210312Sjmallett } else { 1134210312Sjmallett dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen); 1135210312Sjmallett return -EINVAL; 1136210312Sjmallett } 1137210312Sjmallett 1138210312Sjmallett CVMX_MT_3DES_IV(* (uint64_t *) ivp); 1139210312Sjmallett 1140210312Sjmallett /* Load SHA1 IV */ 1141210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[0], 0); 1142210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[1], 1); 1143210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[2], 2); 1144210312Sjmallett 1145210312Sjmallett while (crypt_off > 0 && auth_off > 0) { 1146210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1147210312Sjmallett crypt_off -= 4; 1148210312Sjmallett auth_off -= 4; 1149210312Sjmallett } 1150210312Sjmallett 1151210312Sjmallett while (crypt_len > 0 || auth_len > 0) { 1152210312Sjmallett uint32_t *first = data32; 1153210312Sjmallett mydata.data32[0] = *first; 1154210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1155210312Sjmallett mydata.data32[1] = *data32; 1156210312Sjmallett if (crypt_off <= 0) { 1157210312Sjmallett if (crypt_len > 0) { 1158210312Sjmallett CVMX_MT_3DES_ENC_CBC(*data); 1159210312Sjmallett CVMX_MF_3DES_RESULT(*data); 1160210312Sjmallett crypt_len -= 8; 1161210312Sjmallett } 1162210312Sjmallett } else 1163210312Sjmallett crypt_off -= 8; 1164210312Sjmallett if (auth_off <= 0) { 1165210312Sjmallett if (auth_len > 0) { 1166210312Sjmallett CVM_LOAD_SHA_UNIT(*data, next); 1167210312Sjmallett auth_len -= 8; 1168210312Sjmallett } 1169210312Sjmallett } else 1170210312Sjmallett auth_off -= 8; 1171210312Sjmallett *first = mydata.data32[0]; 1172210312Sjmallett *data32 = mydata.data32[1]; 1173210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1174210312Sjmallett } 1175210312Sjmallett 1176210312Sjmallett /* finish the hash */ 1177210312Sjmallett CVMX_PREFETCH0(od->octo_hmouter); 1178210312Sjmallett#if 0 1179210312Sjmallett if (__predict_false(inplen)) { 1180210312Sjmallett uint64_t tmp = 0; 1181210312Sjmallett uint8_t *p = (uint8_t *) & tmp; 1182210312Sjmallett p[inplen] = 0x80; 1183210312Sjmallett do { 1184210312Sjmallett inplen--; 1185210312Sjmallett p[inplen] = ((uint8_t *) data)[inplen]; 1186210312Sjmallett } while (inplen); 1187210312Sjmallett CVM_LOAD_SHA_UNIT(tmp, next); 1188210312Sjmallett } else { 1189210312Sjmallett CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next); 1190210312Sjmallett } 1191210312Sjmallett#else 1192210312Sjmallett CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next); 1193210312Sjmallett#endif 1194210312Sjmallett 1195210312Sjmallett /* Finish Inner hash */ 1196210312Sjmallett while (next != 7) { 1197210312Sjmallett CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next); 1198210312Sjmallett } 1199210312Sjmallett CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next); 1200210312Sjmallett 1201210312Sjmallett /* Get the inner hash of HMAC */ 1202210312Sjmallett CVMX_MF_HSH_IV(tmp1, 0); 1203210312Sjmallett CVMX_MF_HSH_IV(tmp2, 1); 1204210312Sjmallett tmp3 = 0; 1205210312Sjmallett CVMX_MF_HSH_IV(tmp3, 2); 1206210312Sjmallett 1207210312Sjmallett /* Initialize hash unit */ 1208210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[0], 0); 1209210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[1], 1); 1210210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[2], 2); 1211210312Sjmallett 1212210312Sjmallett CVMX_MT_HSH_DAT(tmp1, 0); 1213210312Sjmallett CVMX_MT_HSH_DAT(tmp2, 1); 1214210312Sjmallett tmp3 |= 0x0000000080000000; 1215210312Sjmallett CVMX_MT_HSH_DAT(tmp3, 2); 1216210312Sjmallett CVMX_MT_HSH_DATZ(3); 1217210312Sjmallett CVMX_MT_HSH_DATZ(4); 1218210312Sjmallett CVMX_MT_HSH_DATZ(5); 1219210312Sjmallett CVMX_MT_HSH_DATZ(6); 1220210312Sjmallett CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3)); 1221210312Sjmallett 1222210312Sjmallett /* save the HMAC */ 1223210312Sjmallett IOV_INIT(iov, data32, data_i, data_l); 1224210312Sjmallett while (icv_off > 0) { 1225210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1226210312Sjmallett icv_off -= 4; 1227210312Sjmallett } 1228210312Sjmallett CVMX_MF_HSH_IV(tmp1, 0); 1229210312Sjmallett *data32 = (uint32_t) (tmp1 >> 32); 1230210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1231210312Sjmallett *data32 = (uint32_t) tmp1; 1232210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1233210312Sjmallett CVMX_MF_HSH_IV(tmp1, 1); 1234210312Sjmallett *data32 = (uint32_t) (tmp1 >> 32); 1235210312Sjmallett 1236210312Sjmallett return 0; 1237210312Sjmallett} 1238210312Sjmallett 1239210312Sjmallettint 1240210312Sjmallettocto_des_cbc_sha1_decrypt( 1241210312Sjmallett struct octo_sess *od, 1242210312Sjmallett struct iovec *iov, size_t iovcnt, size_t iovlen, 1243210312Sjmallett int auth_off, int auth_len, 1244210312Sjmallett int crypt_off, int crypt_len, 1245210312Sjmallett int icv_off, uint8_t *ivp) 1246210312Sjmallett{ 1247210312Sjmallett register int next = 0; 1248210312Sjmallett union { 1249210312Sjmallett uint32_t data32[2]; 1250210312Sjmallett uint64_t data64[1]; 1251210312Sjmallett } mydata; 1252210312Sjmallett uint64_t *data = &mydata.data64[0]; 1253210312Sjmallett uint32_t *data32; 1254210312Sjmallett uint64_t tmp1, tmp2, tmp3; 1255210312Sjmallett int data_i, data_l, alen = auth_len; 1256210312Sjmallett 1257210312Sjmallett dprintf("%s()\n", __func__); 1258210312Sjmallett 1259210312Sjmallett if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL || 1260210312Sjmallett (crypt_off & 0x3) || (crypt_off + crypt_len > iovlen) || 1261210312Sjmallett (crypt_len & 0x7) || 1262210312Sjmallett (auth_len & 0x7) || 1263210312Sjmallett (auth_off & 0x3) || (auth_off + auth_len > iovlen))) { 1264217620Sgonzo dprintf("%s: Bad parameters od=%p iov=%p iovlen=%jd " 1265210312Sjmallett "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d " 1266210312Sjmallett "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen, 1267210312Sjmallett auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp); 1268210312Sjmallett return -EINVAL; 1269210312Sjmallett } 1270210312Sjmallett 1271210312Sjmallett IOV_INIT(iov, data32, data_i, data_l); 1272210312Sjmallett 1273210312Sjmallett CVMX_PREFETCH0(ivp); 1274210312Sjmallett CVMX_PREFETCH0(od->octo_enckey); 1275210312Sjmallett 1276210312Sjmallett /* load 3DES Key */ 1277210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0); 1278210312Sjmallett if (od->octo_encklen == 24) { 1279210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1); 1280210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2); 1281210312Sjmallett } else if (od->octo_encklen == 8) { 1282210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1); 1283210312Sjmallett CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2); 1284210312Sjmallett } else { 1285210312Sjmallett dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen); 1286210312Sjmallett return -EINVAL; 1287210312Sjmallett } 1288210312Sjmallett 1289210312Sjmallett CVMX_MT_3DES_IV(* (uint64_t *) ivp); 1290210312Sjmallett 1291210312Sjmallett /* Load SHA1 IV */ 1292210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[0], 0); 1293210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[1], 1); 1294210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[2], 2); 1295210312Sjmallett 1296210312Sjmallett while (crypt_off > 0 && auth_off > 0) { 1297210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1298210312Sjmallett crypt_off -= 4; 1299210312Sjmallett auth_off -= 4; 1300210312Sjmallett } 1301210312Sjmallett 1302210312Sjmallett while (crypt_len > 0 || auth_len > 0) { 1303210312Sjmallett uint32_t *first = data32; 1304210312Sjmallett mydata.data32[0] = *first; 1305210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1306210312Sjmallett mydata.data32[1] = *data32; 1307210312Sjmallett if (auth_off <= 0) { 1308210312Sjmallett if (auth_len > 0) { 1309210312Sjmallett CVM_LOAD_SHA_UNIT(*data, next); 1310210312Sjmallett auth_len -= 8; 1311210312Sjmallett } 1312210312Sjmallett } else 1313210312Sjmallett auth_off -= 8; 1314210312Sjmallett if (crypt_off <= 0) { 1315210312Sjmallett if (crypt_len > 0) { 1316210312Sjmallett CVMX_MT_3DES_DEC_CBC(*data); 1317210312Sjmallett CVMX_MF_3DES_RESULT(*data); 1318210312Sjmallett crypt_len -= 8; 1319210312Sjmallett } 1320210312Sjmallett } else 1321210312Sjmallett crypt_off -= 8; 1322210312Sjmallett *first = mydata.data32[0]; 1323210312Sjmallett *data32 = mydata.data32[1]; 1324210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1325210312Sjmallett } 1326210312Sjmallett 1327210312Sjmallett /* finish the hash */ 1328210312Sjmallett CVMX_PREFETCH0(od->octo_hmouter); 1329210312Sjmallett#if 0 1330210312Sjmallett if (__predict_false(inplen)) { 1331210312Sjmallett uint64_t tmp = 0; 1332210312Sjmallett uint8_t *p = (uint8_t *) & tmp; 1333210312Sjmallett p[inplen] = 0x80; 1334210312Sjmallett do { 1335210312Sjmallett inplen--; 1336210312Sjmallett p[inplen] = ((uint8_t *) data)[inplen]; 1337210312Sjmallett } while (inplen); 1338210312Sjmallett CVM_LOAD_SHA_UNIT(tmp, next); 1339210312Sjmallett } else { 1340210312Sjmallett CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next); 1341210312Sjmallett } 1342210312Sjmallett#else 1343210312Sjmallett CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next); 1344210312Sjmallett#endif 1345210312Sjmallett 1346210312Sjmallett /* Finish Inner hash */ 1347210312Sjmallett while (next != 7) { 1348210312Sjmallett CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next); 1349210312Sjmallett } 1350210312Sjmallett CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next); 1351210312Sjmallett 1352210312Sjmallett /* Get the inner hash of HMAC */ 1353210312Sjmallett CVMX_MF_HSH_IV(tmp1, 0); 1354210312Sjmallett CVMX_MF_HSH_IV(tmp2, 1); 1355210312Sjmallett tmp3 = 0; 1356210312Sjmallett CVMX_MF_HSH_IV(tmp3, 2); 1357210312Sjmallett 1358210312Sjmallett /* Initialize hash unit */ 1359210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[0], 0); 1360210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[1], 1); 1361210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[2], 2); 1362210312Sjmallett 1363210312Sjmallett CVMX_MT_HSH_DAT(tmp1, 0); 1364210312Sjmallett CVMX_MT_HSH_DAT(tmp2, 1); 1365210312Sjmallett tmp3 |= 0x0000000080000000; 1366210312Sjmallett CVMX_MT_HSH_DAT(tmp3, 2); 1367210312Sjmallett CVMX_MT_HSH_DATZ(3); 1368210312Sjmallett CVMX_MT_HSH_DATZ(4); 1369210312Sjmallett CVMX_MT_HSH_DATZ(5); 1370210312Sjmallett CVMX_MT_HSH_DATZ(6); 1371210312Sjmallett CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3)); 1372210312Sjmallett /* save the HMAC */ 1373210312Sjmallett IOV_INIT(iov, data32, data_i, data_l); 1374210312Sjmallett while (icv_off > 0) { 1375210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1376210312Sjmallett icv_off -= 4; 1377210312Sjmallett } 1378210312Sjmallett CVMX_MF_HSH_IV(tmp1, 0); 1379210312Sjmallett *data32 = (uint32_t) (tmp1 >> 32); 1380210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1381210312Sjmallett *data32 = (uint32_t) tmp1; 1382210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1383210312Sjmallett CVMX_MF_HSH_IV(tmp1, 1); 1384210312Sjmallett *data32 = (uint32_t) (tmp1 >> 32); 1385210312Sjmallett 1386210312Sjmallett return 0; 1387210312Sjmallett} 1388210312Sjmallett 1389210312Sjmallett/****************************************************************************/ 1390210312Sjmallett/* AES MD5 */ 1391210312Sjmallett 1392210312Sjmallettint 1393210312Sjmallettocto_aes_cbc_md5_encrypt( 1394210312Sjmallett struct octo_sess *od, 1395210312Sjmallett struct iovec *iov, size_t iovcnt, size_t iovlen, 1396210312Sjmallett int auth_off, int auth_len, 1397210312Sjmallett int crypt_off, int crypt_len, 1398210312Sjmallett int icv_off, uint8_t *ivp) 1399210312Sjmallett{ 1400210312Sjmallett register int next = 0; 1401210312Sjmallett union { 1402210312Sjmallett uint32_t data32[2]; 1403210312Sjmallett uint64_t data64[1]; 1404210312Sjmallett } mydata[2]; 1405210312Sjmallett uint64_t *pdata = &mydata[0].data64[0]; 1406210312Sjmallett uint64_t *data = &mydata[1].data64[0]; 1407210312Sjmallett uint32_t *data32; 1408210312Sjmallett uint64_t tmp1, tmp2; 1409210312Sjmallett int data_i, data_l, alen = auth_len; 1410210312Sjmallett 1411210312Sjmallett dprintf("%s()\n", __func__); 1412210312Sjmallett 1413210312Sjmallett if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL || 1414210312Sjmallett (crypt_off & 0x3) || (crypt_off + crypt_len > iovlen) || 1415210312Sjmallett (crypt_len & 0x7) || 1416210312Sjmallett (auth_len & 0x7) || 1417210312Sjmallett (auth_off & 0x3) || (auth_off + auth_len > iovlen))) { 1418217620Sgonzo dprintf("%s: Bad parameters od=%p iov=%p iovlen=%jd " 1419210312Sjmallett "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d " 1420210312Sjmallett "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen, 1421210312Sjmallett auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp); 1422210312Sjmallett return -EINVAL; 1423210312Sjmallett } 1424210312Sjmallett 1425210312Sjmallett IOV_INIT(iov, data32, data_i, data_l); 1426210312Sjmallett 1427210312Sjmallett CVMX_PREFETCH0(ivp); 1428210312Sjmallett CVMX_PREFETCH0(od->octo_enckey); 1429210312Sjmallett 1430210312Sjmallett /* load AES Key */ 1431210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0); 1432210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1); 1433210312Sjmallett 1434210312Sjmallett if (od->octo_encklen == 16) { 1435210312Sjmallett CVMX_MT_AES_KEY(0x0, 2); 1436210312Sjmallett CVMX_MT_AES_KEY(0x0, 3); 1437210312Sjmallett } else if (od->octo_encklen == 24) { 1438210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2); 1439210312Sjmallett CVMX_MT_AES_KEY(0x0, 3); 1440210312Sjmallett } else if (od->octo_encklen == 32) { 1441210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2); 1442210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3); 1443210312Sjmallett } else { 1444210312Sjmallett dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen); 1445210312Sjmallett return -EINVAL; 1446210312Sjmallett } 1447210312Sjmallett CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1); 1448210312Sjmallett 1449210312Sjmallett CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0); 1450210312Sjmallett CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1); 1451210312Sjmallett 1452210312Sjmallett /* Load MD5 IV */ 1453210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[0], 0); 1454210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[1], 1); 1455210312Sjmallett 1456210312Sjmallett while (crypt_off > 0 && auth_off > 0) { 1457210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1458210312Sjmallett crypt_off -= 4; 1459210312Sjmallett auth_off -= 4; 1460210312Sjmallett } 1461210312Sjmallett 1462210312Sjmallett while (crypt_len > 0 || auth_len > 0) { 1463210312Sjmallett uint32_t *pdata32[3]; 1464210312Sjmallett 1465210312Sjmallett pdata32[0] = data32; 1466210312Sjmallett mydata[0].data32[0] = *data32; 1467210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1468210312Sjmallett 1469210312Sjmallett pdata32[1] = data32; 1470210312Sjmallett mydata[0].data32[1] = *data32; 1471210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1472210312Sjmallett 1473210312Sjmallett pdata32[2] = data32; 1474210312Sjmallett mydata[1].data32[0] = *data32; 1475210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1476210312Sjmallett 1477210312Sjmallett mydata[1].data32[1] = *data32; 1478210312Sjmallett 1479210312Sjmallett 1480210312Sjmallett if (crypt_off <= 0) { 1481210312Sjmallett if (crypt_len > 0) { 1482210312Sjmallett CVMX_MT_AES_ENC_CBC0(*pdata); 1483210312Sjmallett CVMX_MT_AES_ENC_CBC1(*data); 1484210312Sjmallett CVMX_MF_AES_RESULT(*pdata, 0); 1485210312Sjmallett CVMX_MF_AES_RESULT(*data, 1); 1486210312Sjmallett crypt_len -= 16; 1487210312Sjmallett } 1488210312Sjmallett } else 1489210312Sjmallett crypt_off -= 16; 1490210312Sjmallett 1491210312Sjmallett if (auth_off <= 0) { 1492210312Sjmallett if (auth_len > 0) { 1493210312Sjmallett CVM_LOAD_MD5_UNIT(*pdata, next); 1494210312Sjmallett CVM_LOAD_MD5_UNIT(*data, next); 1495210312Sjmallett auth_len -= 16; 1496210312Sjmallett } 1497210312Sjmallett } else 1498210312Sjmallett auth_off -= 16; 1499210312Sjmallett 1500210312Sjmallett *pdata32[0] = mydata[0].data32[0]; 1501210312Sjmallett *pdata32[1] = mydata[0].data32[1]; 1502210312Sjmallett *pdata32[2] = mydata[1].data32[0]; 1503210312Sjmallett *data32 = mydata[1].data32[1]; 1504210312Sjmallett 1505210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1506210312Sjmallett } 1507210312Sjmallett 1508210312Sjmallett /* finish the hash */ 1509210312Sjmallett CVMX_PREFETCH0(od->octo_hmouter); 1510210312Sjmallett#if 0 1511210312Sjmallett if (__predict_false(inplen)) { 1512210312Sjmallett uint64_t tmp = 0; 1513210312Sjmallett uint8_t *p = (uint8_t *) & tmp; 1514210312Sjmallett p[inplen] = 0x80; 1515210312Sjmallett do { 1516210312Sjmallett inplen--; 1517210312Sjmallett p[inplen] = ((uint8_t *) data)[inplen]; 1518210312Sjmallett } while (inplen); 1519210312Sjmallett CVM_LOAD_MD5_UNIT(tmp, next); 1520210312Sjmallett } else { 1521210312Sjmallett CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next); 1522210312Sjmallett } 1523210312Sjmallett#else 1524210312Sjmallett CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next); 1525210312Sjmallett#endif 1526210312Sjmallett 1527210312Sjmallett /* Finish Inner hash */ 1528210312Sjmallett while (next != 7) { 1529210312Sjmallett CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next); 1530210312Sjmallett } 1531210312Sjmallett CVMX_ES64(tmp1, ((alen + 64) << 3)); 1532210312Sjmallett CVM_LOAD_MD5_UNIT(tmp1, next); 1533210312Sjmallett 1534210312Sjmallett /* Get the inner hash of HMAC */ 1535210312Sjmallett CVMX_MF_HSH_IV(tmp1, 0); 1536210312Sjmallett CVMX_MF_HSH_IV(tmp2, 1); 1537210312Sjmallett 1538210312Sjmallett /* Initialize hash unit */ 1539210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[0], 0); 1540210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[1], 1); 1541210312Sjmallett 1542210312Sjmallett CVMX_MT_HSH_DAT(tmp1, 0); 1543210312Sjmallett CVMX_MT_HSH_DAT(tmp2, 1); 1544210312Sjmallett CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2); 1545210312Sjmallett CVMX_MT_HSH_DATZ(3); 1546210312Sjmallett CVMX_MT_HSH_DATZ(4); 1547210312Sjmallett CVMX_MT_HSH_DATZ(5); 1548210312Sjmallett CVMX_MT_HSH_DATZ(6); 1549210312Sjmallett CVMX_ES64(tmp1, ((64 + 16) << 3)); 1550210312Sjmallett CVMX_MT_HSH_STARTMD5(tmp1); 1551210312Sjmallett 1552210312Sjmallett /* save the HMAC */ 1553210312Sjmallett IOV_INIT(iov, data32, data_i, data_l); 1554210312Sjmallett while (icv_off > 0) { 1555210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1556210312Sjmallett icv_off -= 4; 1557210312Sjmallett } 1558210312Sjmallett CVMX_MF_HSH_IV(tmp1, 0); 1559210312Sjmallett *data32 = (uint32_t) (tmp1 >> 32); 1560210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1561210312Sjmallett *data32 = (uint32_t) tmp1; 1562210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1563210312Sjmallett CVMX_MF_HSH_IV(tmp1, 1); 1564210312Sjmallett *data32 = (uint32_t) (tmp1 >> 32); 1565210312Sjmallett 1566210312Sjmallett return 0; 1567210312Sjmallett} 1568210312Sjmallett 1569210312Sjmallettint 1570210312Sjmallettocto_aes_cbc_md5_decrypt( 1571210312Sjmallett struct octo_sess *od, 1572210312Sjmallett struct iovec *iov, size_t iovcnt, size_t iovlen, 1573210312Sjmallett int auth_off, int auth_len, 1574210312Sjmallett int crypt_off, int crypt_len, 1575210312Sjmallett int icv_off, uint8_t *ivp) 1576210312Sjmallett{ 1577210312Sjmallett register int next = 0; 1578210312Sjmallett union { 1579210312Sjmallett uint32_t data32[2]; 1580210312Sjmallett uint64_t data64[1]; 1581210312Sjmallett } mydata[2]; 1582210312Sjmallett uint64_t *pdata = &mydata[0].data64[0]; 1583210312Sjmallett uint64_t *data = &mydata[1].data64[0]; 1584210312Sjmallett uint32_t *data32; 1585210312Sjmallett uint64_t tmp1, tmp2; 1586210312Sjmallett int data_i, data_l, alen = auth_len; 1587210312Sjmallett 1588210312Sjmallett dprintf("%s()\n", __func__); 1589210312Sjmallett 1590210312Sjmallett if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL || 1591210312Sjmallett (crypt_off & 0x3) || (crypt_off + crypt_len > iovlen) || 1592210312Sjmallett (crypt_len & 0x7) || 1593210312Sjmallett (auth_len & 0x7) || 1594210312Sjmallett (auth_off & 0x3) || (auth_off + auth_len > iovlen))) { 1595217620Sgonzo dprintf("%s: Bad parameters od=%p iov=%p iovlen=%jd " 1596210312Sjmallett "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d " 1597210312Sjmallett "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen, 1598210312Sjmallett auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp); 1599210312Sjmallett return -EINVAL; 1600210312Sjmallett } 1601210312Sjmallett 1602210312Sjmallett IOV_INIT(iov, data32, data_i, data_l); 1603210312Sjmallett 1604210312Sjmallett CVMX_PREFETCH0(ivp); 1605210312Sjmallett CVMX_PREFETCH0(od->octo_enckey); 1606210312Sjmallett 1607210312Sjmallett /* load AES Key */ 1608210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0); 1609210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1); 1610210312Sjmallett 1611210312Sjmallett if (od->octo_encklen == 16) { 1612210312Sjmallett CVMX_MT_AES_KEY(0x0, 2); 1613210312Sjmallett CVMX_MT_AES_KEY(0x0, 3); 1614210312Sjmallett } else if (od->octo_encklen == 24) { 1615210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2); 1616210312Sjmallett CVMX_MT_AES_KEY(0x0, 3); 1617210312Sjmallett } else if (od->octo_encklen == 32) { 1618210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2); 1619210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3); 1620210312Sjmallett } else { 1621210312Sjmallett dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen); 1622210312Sjmallett return -EINVAL; 1623210312Sjmallett } 1624210312Sjmallett CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1); 1625210312Sjmallett 1626210312Sjmallett CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0); 1627210312Sjmallett CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1); 1628210312Sjmallett 1629210312Sjmallett /* Load MD5 IV */ 1630210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[0], 0); 1631210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[1], 1); 1632210312Sjmallett 1633210312Sjmallett while (crypt_off > 0 && auth_off > 0) { 1634210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1635210312Sjmallett crypt_off -= 4; 1636210312Sjmallett auth_off -= 4; 1637210312Sjmallett } 1638210312Sjmallett 1639210312Sjmallett while (crypt_len > 0 || auth_len > 0) { 1640210312Sjmallett uint32_t *pdata32[3]; 1641210312Sjmallett 1642210312Sjmallett pdata32[0] = data32; 1643210312Sjmallett mydata[0].data32[0] = *data32; 1644210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1645210312Sjmallett pdata32[1] = data32; 1646210312Sjmallett mydata[0].data32[1] = *data32; 1647210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1648210312Sjmallett pdata32[2] = data32; 1649210312Sjmallett mydata[1].data32[0] = *data32; 1650210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1651210312Sjmallett mydata[1].data32[1] = *data32; 1652210312Sjmallett 1653210312Sjmallett if (auth_off <= 0) { 1654210312Sjmallett if (auth_len > 0) { 1655210312Sjmallett CVM_LOAD_MD5_UNIT(*pdata, next); 1656210312Sjmallett CVM_LOAD_MD5_UNIT(*data, next); 1657210312Sjmallett auth_len -= 16; 1658210312Sjmallett } 1659210312Sjmallett } else 1660210312Sjmallett auth_off -= 16; 1661210312Sjmallett 1662210312Sjmallett if (crypt_off <= 0) { 1663210312Sjmallett if (crypt_len > 0) { 1664210312Sjmallett CVMX_MT_AES_DEC_CBC0(*pdata); 1665210312Sjmallett CVMX_MT_AES_DEC_CBC1(*data); 1666210312Sjmallett CVMX_MF_AES_RESULT(*pdata, 0); 1667210312Sjmallett CVMX_MF_AES_RESULT(*data, 1); 1668210312Sjmallett crypt_len -= 16; 1669210312Sjmallett } 1670210312Sjmallett } else 1671210312Sjmallett crypt_off -= 16; 1672210312Sjmallett 1673210312Sjmallett *pdata32[0] = mydata[0].data32[0]; 1674210312Sjmallett *pdata32[1] = mydata[0].data32[1]; 1675210312Sjmallett *pdata32[2] = mydata[1].data32[0]; 1676210312Sjmallett *data32 = mydata[1].data32[1]; 1677210312Sjmallett 1678210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1679210312Sjmallett } 1680210312Sjmallett 1681210312Sjmallett /* finish the hash */ 1682210312Sjmallett CVMX_PREFETCH0(od->octo_hmouter); 1683210312Sjmallett#if 0 1684210312Sjmallett if (__predict_false(inplen)) { 1685210312Sjmallett uint64_t tmp = 0; 1686210312Sjmallett uint8_t *p = (uint8_t *) & tmp; 1687210312Sjmallett p[inplen] = 0x80; 1688210312Sjmallett do { 1689210312Sjmallett inplen--; 1690210312Sjmallett p[inplen] = ((uint8_t *) data)[inplen]; 1691210312Sjmallett } while (inplen); 1692210312Sjmallett CVM_LOAD_MD5_UNIT(tmp, next); 1693210312Sjmallett } else { 1694210312Sjmallett CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next); 1695210312Sjmallett } 1696210312Sjmallett#else 1697210312Sjmallett CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next); 1698210312Sjmallett#endif 1699210312Sjmallett 1700210312Sjmallett /* Finish Inner hash */ 1701210312Sjmallett while (next != 7) { 1702210312Sjmallett CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next); 1703210312Sjmallett } 1704210312Sjmallett CVMX_ES64(tmp1, ((alen + 64) << 3)); 1705210312Sjmallett CVM_LOAD_MD5_UNIT(tmp1, next); 1706210312Sjmallett 1707210312Sjmallett /* Get the inner hash of HMAC */ 1708210312Sjmallett CVMX_MF_HSH_IV(tmp1, 0); 1709210312Sjmallett CVMX_MF_HSH_IV(tmp2, 1); 1710210312Sjmallett 1711210312Sjmallett /* Initialize hash unit */ 1712210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[0], 0); 1713210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[1], 1); 1714210312Sjmallett 1715210312Sjmallett CVMX_MT_HSH_DAT(tmp1, 0); 1716210312Sjmallett CVMX_MT_HSH_DAT(tmp2, 1); 1717210312Sjmallett CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2); 1718210312Sjmallett CVMX_MT_HSH_DATZ(3); 1719210312Sjmallett CVMX_MT_HSH_DATZ(4); 1720210312Sjmallett CVMX_MT_HSH_DATZ(5); 1721210312Sjmallett CVMX_MT_HSH_DATZ(6); 1722210312Sjmallett CVMX_ES64(tmp1, ((64 + 16) << 3)); 1723210312Sjmallett CVMX_MT_HSH_STARTMD5(tmp1); 1724210312Sjmallett 1725210312Sjmallett /* save the HMAC */ 1726210312Sjmallett IOV_INIT(iov, data32, data_i, data_l); 1727210312Sjmallett while (icv_off > 0) { 1728210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1729210312Sjmallett icv_off -= 4; 1730210312Sjmallett } 1731210312Sjmallett CVMX_MF_HSH_IV(tmp1, 0); 1732210312Sjmallett *data32 = (uint32_t) (tmp1 >> 32); 1733210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1734210312Sjmallett *data32 = (uint32_t) tmp1; 1735210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1736210312Sjmallett CVMX_MF_HSH_IV(tmp1, 1); 1737210312Sjmallett *data32 = (uint32_t) (tmp1 >> 32); 1738210312Sjmallett 1739210312Sjmallett return 0; 1740210312Sjmallett} 1741210312Sjmallett 1742210312Sjmallett/****************************************************************************/ 1743210312Sjmallett/* AES SHA1 */ 1744210312Sjmallett 1745210312Sjmallettint 1746210312Sjmallettocto_aes_cbc_sha1_encrypt( 1747210312Sjmallett struct octo_sess *od, 1748210312Sjmallett struct iovec *iov, size_t iovcnt, size_t iovlen, 1749210312Sjmallett int auth_off, int auth_len, 1750210312Sjmallett int crypt_off, int crypt_len, 1751210312Sjmallett int icv_off, uint8_t *ivp) 1752210312Sjmallett{ 1753210312Sjmallett register int next = 0; 1754210312Sjmallett union { 1755210312Sjmallett uint32_t data32[2]; 1756210312Sjmallett uint64_t data64[1]; 1757210312Sjmallett } mydata[2]; 1758210312Sjmallett uint64_t *pdata = &mydata[0].data64[0]; 1759210312Sjmallett uint64_t *data = &mydata[1].data64[0]; 1760210312Sjmallett uint32_t *data32; 1761210312Sjmallett uint64_t tmp1, tmp2, tmp3; 1762210312Sjmallett int data_i, data_l, alen = auth_len; 1763210312Sjmallett 1764210312Sjmallett dprintf("%s()\n", __func__); 1765210312Sjmallett 1766210312Sjmallett if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL || 1767210312Sjmallett (crypt_off & 0x3) || (crypt_off + crypt_len > iovlen) || 1768210312Sjmallett (crypt_len & 0x7) || 1769210312Sjmallett (auth_len & 0x7) || 1770210312Sjmallett (auth_off & 0x3) || (auth_off + auth_len > iovlen))) { 1771217620Sgonzo dprintf("%s: Bad parameters od=%p iov=%p iovlen=%jd " 1772210312Sjmallett "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d " 1773210312Sjmallett "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen, 1774210312Sjmallett auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp); 1775210312Sjmallett return -EINVAL; 1776210312Sjmallett } 1777210312Sjmallett 1778210312Sjmallett IOV_INIT(iov, data32, data_i, data_l); 1779210312Sjmallett 1780210312Sjmallett CVMX_PREFETCH0(ivp); 1781210312Sjmallett CVMX_PREFETCH0(od->octo_enckey); 1782210312Sjmallett 1783210312Sjmallett /* load AES Key */ 1784210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0); 1785210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1); 1786210312Sjmallett 1787210312Sjmallett if (od->octo_encklen == 16) { 1788210312Sjmallett CVMX_MT_AES_KEY(0x0, 2); 1789210312Sjmallett CVMX_MT_AES_KEY(0x0, 3); 1790210312Sjmallett } else if (od->octo_encklen == 24) { 1791210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2); 1792210312Sjmallett CVMX_MT_AES_KEY(0x0, 3); 1793210312Sjmallett } else if (od->octo_encklen == 32) { 1794210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2); 1795210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3); 1796210312Sjmallett } else { 1797210312Sjmallett dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen); 1798210312Sjmallett return -EINVAL; 1799210312Sjmallett } 1800210312Sjmallett CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1); 1801210312Sjmallett 1802210312Sjmallett CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0); 1803210312Sjmallett CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1); 1804210312Sjmallett 1805210312Sjmallett /* Load SHA IV */ 1806210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[0], 0); 1807210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[1], 1); 1808210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[2], 2); 1809210312Sjmallett 1810210312Sjmallett while (crypt_off > 0 && auth_off > 0) { 1811210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1812210312Sjmallett crypt_off -= 4; 1813210312Sjmallett auth_off -= 4; 1814210312Sjmallett } 1815210312Sjmallett 1816210312Sjmallett while (crypt_len > 0 || auth_len > 0) { 1817210312Sjmallett uint32_t *pdata32[3]; 1818210312Sjmallett 1819210312Sjmallett pdata32[0] = data32; 1820210312Sjmallett mydata[0].data32[0] = *data32; 1821210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1822210312Sjmallett pdata32[1] = data32; 1823210312Sjmallett mydata[0].data32[1] = *data32; 1824210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1825210312Sjmallett pdata32[2] = data32; 1826210312Sjmallett mydata[1].data32[0] = *data32; 1827210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1828210312Sjmallett mydata[1].data32[1] = *data32; 1829210312Sjmallett 1830210312Sjmallett 1831210312Sjmallett if (crypt_off <= 0) { 1832210312Sjmallett if (crypt_len > 0) { 1833210312Sjmallett CVMX_MT_AES_ENC_CBC0(*pdata); 1834210312Sjmallett CVMX_MT_AES_ENC_CBC1(*data); 1835210312Sjmallett CVMX_MF_AES_RESULT(*pdata, 0); 1836210312Sjmallett CVMX_MF_AES_RESULT(*data, 1); 1837210312Sjmallett crypt_len -= 16; 1838210312Sjmallett } 1839210312Sjmallett } else 1840210312Sjmallett crypt_off -= 16; 1841210312Sjmallett 1842210312Sjmallett if (auth_off <= 0) { 1843210312Sjmallett if (auth_len > 0) { 1844210312Sjmallett CVM_LOAD_SHA_UNIT(*pdata, next); 1845210312Sjmallett CVM_LOAD_SHA_UNIT(*data, next); 1846210312Sjmallett auth_len -= 16; 1847210312Sjmallett } 1848210312Sjmallett } else 1849210312Sjmallett auth_off -= 16; 1850210312Sjmallett 1851210312Sjmallett *pdata32[0] = mydata[0].data32[0]; 1852210312Sjmallett *pdata32[1] = mydata[0].data32[1]; 1853210312Sjmallett *pdata32[2] = mydata[1].data32[0]; 1854210312Sjmallett *data32 = mydata[1].data32[1]; 1855210312Sjmallett 1856210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1857210312Sjmallett } 1858210312Sjmallett 1859210312Sjmallett /* finish the hash */ 1860210312Sjmallett CVMX_PREFETCH0(od->octo_hmouter); 1861210312Sjmallett#if 0 1862210312Sjmallett if (__predict_false(inplen)) { 1863210312Sjmallett uint64_t tmp = 0; 1864210312Sjmallett uint8_t *p = (uint8_t *) & tmp; 1865210312Sjmallett p[inplen] = 0x80; 1866210312Sjmallett do { 1867210312Sjmallett inplen--; 1868210312Sjmallett p[inplen] = ((uint8_t *) data)[inplen]; 1869210312Sjmallett } while (inplen); 1870210312Sjmallett CVM_LOAD_SHA_UNIT(tmp, next); 1871210312Sjmallett } else { 1872210312Sjmallett CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next); 1873210312Sjmallett } 1874210312Sjmallett#else 1875210312Sjmallett CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next); 1876210312Sjmallett#endif 1877210312Sjmallett 1878210312Sjmallett /* Finish Inner hash */ 1879210312Sjmallett while (next != 7) { 1880210312Sjmallett CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next); 1881210312Sjmallett } 1882210312Sjmallett CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next); 1883210312Sjmallett 1884210312Sjmallett /* Get the inner hash of HMAC */ 1885210312Sjmallett CVMX_MF_HSH_IV(tmp1, 0); 1886210312Sjmallett CVMX_MF_HSH_IV(tmp2, 1); 1887210312Sjmallett tmp3 = 0; 1888210312Sjmallett CVMX_MF_HSH_IV(tmp3, 2); 1889210312Sjmallett 1890210312Sjmallett /* Initialize hash unit */ 1891210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[0], 0); 1892210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[1], 1); 1893210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[2], 2); 1894210312Sjmallett 1895210312Sjmallett CVMX_MT_HSH_DAT(tmp1, 0); 1896210312Sjmallett CVMX_MT_HSH_DAT(tmp2, 1); 1897210312Sjmallett tmp3 |= 0x0000000080000000; 1898210312Sjmallett CVMX_MT_HSH_DAT(tmp3, 2); 1899210312Sjmallett CVMX_MT_HSH_DATZ(3); 1900210312Sjmallett CVMX_MT_HSH_DATZ(4); 1901210312Sjmallett CVMX_MT_HSH_DATZ(5); 1902210312Sjmallett CVMX_MT_HSH_DATZ(6); 1903210312Sjmallett CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3)); 1904210312Sjmallett 1905210312Sjmallett /* finish the hash */ 1906210312Sjmallett CVMX_PREFETCH0(od->octo_hmouter); 1907210312Sjmallett#if 0 1908210312Sjmallett if (__predict_false(inplen)) { 1909210312Sjmallett uint64_t tmp = 0; 1910210312Sjmallett uint8_t *p = (uint8_t *) & tmp; 1911210312Sjmallett p[inplen] = 0x80; 1912210312Sjmallett do { 1913210312Sjmallett inplen--; 1914210312Sjmallett p[inplen] = ((uint8_t *) data)[inplen]; 1915210312Sjmallett } while (inplen); 1916210312Sjmallett CVM_LOAD_MD5_UNIT(tmp, next); 1917210312Sjmallett } else { 1918210312Sjmallett CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next); 1919210312Sjmallett } 1920210312Sjmallett#else 1921210312Sjmallett CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next); 1922210312Sjmallett#endif 1923210312Sjmallett 1924210312Sjmallett /* save the HMAC */ 1925210312Sjmallett IOV_INIT(iov, data32, data_i, data_l); 1926210312Sjmallett while (icv_off > 0) { 1927210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1928210312Sjmallett icv_off -= 4; 1929210312Sjmallett } 1930210312Sjmallett CVMX_MF_HSH_IV(tmp1, 0); 1931210312Sjmallett *data32 = (uint32_t) (tmp1 >> 32); 1932210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1933210312Sjmallett *data32 = (uint32_t) tmp1; 1934210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 1935210312Sjmallett CVMX_MF_HSH_IV(tmp1, 1); 1936210312Sjmallett *data32 = (uint32_t) (tmp1 >> 32); 1937210312Sjmallett 1938210312Sjmallett return 0; 1939210312Sjmallett} 1940210312Sjmallett 1941210312Sjmallettint 1942210312Sjmallettocto_aes_cbc_sha1_decrypt( 1943210312Sjmallett struct octo_sess *od, 1944210312Sjmallett struct iovec *iov, size_t iovcnt, size_t iovlen, 1945210312Sjmallett int auth_off, int auth_len, 1946210312Sjmallett int crypt_off, int crypt_len, 1947210312Sjmallett int icv_off, uint8_t *ivp) 1948210312Sjmallett{ 1949210312Sjmallett register int next = 0; 1950210312Sjmallett union { 1951210312Sjmallett uint32_t data32[2]; 1952210312Sjmallett uint64_t data64[1]; 1953210312Sjmallett } mydata[2]; 1954210312Sjmallett uint64_t *pdata = &mydata[0].data64[0]; 1955210312Sjmallett uint64_t *data = &mydata[1].data64[0]; 1956210312Sjmallett uint32_t *data32; 1957210312Sjmallett uint64_t tmp1, tmp2, tmp3; 1958210312Sjmallett int data_i, data_l, alen = auth_len; 1959210312Sjmallett 1960210312Sjmallett dprintf("%s()\n", __func__); 1961210312Sjmallett 1962210312Sjmallett if (__predict_false(od == NULL || iov==NULL || iovlen==0 || ivp==NULL || 1963210312Sjmallett (crypt_off & 0x3) || (crypt_off + crypt_len > iovlen) || 1964210312Sjmallett (crypt_len & 0x7) || 1965210312Sjmallett (auth_len & 0x7) || 1966210312Sjmallett (auth_off & 0x3) || (auth_off + auth_len > iovlen))) { 1967217620Sgonzo dprintf("%s: Bad parameters od=%p iov=%p iovlen=%jd " 1968210312Sjmallett "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d " 1969210312Sjmallett "icv_off=%d ivp=%p\n", __func__, od, iov, iovlen, 1970210312Sjmallett auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp); 1971210312Sjmallett return -EINVAL; 1972210312Sjmallett } 1973210312Sjmallett 1974210312Sjmallett IOV_INIT(iov, data32, data_i, data_l); 1975210312Sjmallett 1976210312Sjmallett CVMX_PREFETCH0(ivp); 1977210312Sjmallett CVMX_PREFETCH0(od->octo_enckey); 1978210312Sjmallett 1979210312Sjmallett /* load AES Key */ 1980210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0); 1981210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1); 1982210312Sjmallett 1983210312Sjmallett if (od->octo_encklen == 16) { 1984210312Sjmallett CVMX_MT_AES_KEY(0x0, 2); 1985210312Sjmallett CVMX_MT_AES_KEY(0x0, 3); 1986210312Sjmallett } else if (od->octo_encklen == 24) { 1987210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2); 1988210312Sjmallett CVMX_MT_AES_KEY(0x0, 3); 1989210312Sjmallett } else if (od->octo_encklen == 32) { 1990210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2); 1991210312Sjmallett CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3); 1992210312Sjmallett } else { 1993210312Sjmallett dprintf("%s: Bad key length %d\n", __func__, od->octo_encklen); 1994210312Sjmallett return -EINVAL; 1995210312Sjmallett } 1996210312Sjmallett CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1); 1997210312Sjmallett 1998210312Sjmallett CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0); 1999210312Sjmallett CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1); 2000210312Sjmallett 2001210312Sjmallett /* Load MD5 IV */ 2002210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[0], 0); 2003210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[1], 1); 2004210312Sjmallett CVMX_MT_HSH_IV(od->octo_hminner[2], 2); 2005210312Sjmallett 2006210312Sjmallett while (crypt_off > 0 && auth_off > 0) { 2007210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 2008210312Sjmallett crypt_off -= 4; 2009210312Sjmallett auth_off -= 4; 2010210312Sjmallett } 2011210312Sjmallett 2012210312Sjmallett while (crypt_len > 0 || auth_len > 0) { 2013210312Sjmallett uint32_t *pdata32[3]; 2014210312Sjmallett 2015210312Sjmallett pdata32[0] = data32; 2016210312Sjmallett mydata[0].data32[0] = *data32; 2017210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 2018210312Sjmallett pdata32[1] = data32; 2019210312Sjmallett mydata[0].data32[1] = *data32; 2020210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 2021210312Sjmallett pdata32[2] = data32; 2022210312Sjmallett mydata[1].data32[0] = *data32; 2023210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 2024210312Sjmallett mydata[1].data32[1] = *data32; 2025210312Sjmallett 2026210312Sjmallett if (auth_off <= 0) { 2027210312Sjmallett if (auth_len > 0) { 2028210312Sjmallett CVM_LOAD_SHA_UNIT(*pdata, next); 2029210312Sjmallett CVM_LOAD_SHA_UNIT(*data, next); 2030210312Sjmallett auth_len -= 16; 2031210312Sjmallett } 2032210312Sjmallett } else 2033210312Sjmallett auth_off -= 16; 2034210312Sjmallett 2035210312Sjmallett if (crypt_off <= 0) { 2036210312Sjmallett if (crypt_len > 0) { 2037210312Sjmallett CVMX_MT_AES_DEC_CBC0(*pdata); 2038210312Sjmallett CVMX_MT_AES_DEC_CBC1(*data); 2039210312Sjmallett CVMX_MF_AES_RESULT(*pdata, 0); 2040210312Sjmallett CVMX_MF_AES_RESULT(*data, 1); 2041210312Sjmallett crypt_len -= 16; 2042210312Sjmallett } 2043210312Sjmallett } else 2044210312Sjmallett crypt_off -= 16; 2045210312Sjmallett 2046210312Sjmallett *pdata32[0] = mydata[0].data32[0]; 2047210312Sjmallett *pdata32[1] = mydata[0].data32[1]; 2048210312Sjmallett *pdata32[2] = mydata[1].data32[0]; 2049210312Sjmallett *data32 = mydata[1].data32[1]; 2050210312Sjmallett 2051210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 2052210312Sjmallett } 2053210312Sjmallett 2054210312Sjmallett /* finish the hash */ 2055210312Sjmallett CVMX_PREFETCH0(od->octo_hmouter); 2056210312Sjmallett#if 0 2057210312Sjmallett if (__predict_false(inplen)) { 2058210312Sjmallett uint64_t tmp = 0; 2059210312Sjmallett uint8_t *p = (uint8_t *) & tmp; 2060210312Sjmallett p[inplen] = 0x80; 2061210312Sjmallett do { 2062210312Sjmallett inplen--; 2063210312Sjmallett p[inplen] = ((uint8_t *) data)[inplen]; 2064210312Sjmallett } while (inplen); 2065210312Sjmallett CVM_LOAD_SHA_UNIT(tmp, next); 2066210312Sjmallett } else { 2067210312Sjmallett CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next); 2068210312Sjmallett } 2069210312Sjmallett#else 2070210312Sjmallett CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next); 2071210312Sjmallett#endif 2072210312Sjmallett 2073210312Sjmallett /* Finish Inner hash */ 2074210312Sjmallett while (next != 7) { 2075210312Sjmallett CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next); 2076210312Sjmallett } 2077210312Sjmallett CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next); 2078210312Sjmallett 2079210312Sjmallett /* Get the inner hash of HMAC */ 2080210312Sjmallett CVMX_MF_HSH_IV(tmp1, 0); 2081210312Sjmallett CVMX_MF_HSH_IV(tmp2, 1); 2082210312Sjmallett tmp3 = 0; 2083210312Sjmallett CVMX_MF_HSH_IV(tmp3, 2); 2084210312Sjmallett 2085210312Sjmallett /* Initialize hash unit */ 2086210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[0], 0); 2087210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[1], 1); 2088210312Sjmallett CVMX_MT_HSH_IV(od->octo_hmouter[2], 2); 2089210312Sjmallett 2090210312Sjmallett CVMX_MT_HSH_DAT(tmp1, 0); 2091210312Sjmallett CVMX_MT_HSH_DAT(tmp2, 1); 2092210312Sjmallett tmp3 |= 0x0000000080000000; 2093210312Sjmallett CVMX_MT_HSH_DAT(tmp3, 2); 2094210312Sjmallett CVMX_MT_HSH_DATZ(3); 2095210312Sjmallett CVMX_MT_HSH_DATZ(4); 2096210312Sjmallett CVMX_MT_HSH_DATZ(5); 2097210312Sjmallett CVMX_MT_HSH_DATZ(6); 2098210312Sjmallett CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3)); 2099210312Sjmallett 2100210312Sjmallett /* finish the hash */ 2101210312Sjmallett CVMX_PREFETCH0(od->octo_hmouter); 2102210312Sjmallett#if 0 2103210312Sjmallett if (__predict_false(inplen)) { 2104210312Sjmallett uint64_t tmp = 0; 2105210312Sjmallett uint8_t *p = (uint8_t *) & tmp; 2106210312Sjmallett p[inplen] = 0x80; 2107210312Sjmallett do { 2108210312Sjmallett inplen--; 2109210312Sjmallett p[inplen] = ((uint8_t *) data)[inplen]; 2110210312Sjmallett } while (inplen); 2111210312Sjmallett CVM_LOAD_MD5_UNIT(tmp, next); 2112210312Sjmallett } else { 2113210312Sjmallett CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next); 2114210312Sjmallett } 2115210312Sjmallett#else 2116210312Sjmallett CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next); 2117210312Sjmallett#endif 2118210312Sjmallett 2119210312Sjmallett /* save the HMAC */ 2120210312Sjmallett IOV_INIT(iov, data32, data_i, data_l); 2121210312Sjmallett while (icv_off > 0) { 2122210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 2123210312Sjmallett icv_off -= 4; 2124210312Sjmallett } 2125210312Sjmallett CVMX_MF_HSH_IV(tmp1, 0); 2126210312Sjmallett *data32 = (uint32_t) (tmp1 >> 32); 2127210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 2128210312Sjmallett *data32 = (uint32_t) tmp1; 2129210312Sjmallett IOV_CONSUME(iov, data32, data_i, data_l); 2130210312Sjmallett CVMX_MF_HSH_IV(tmp1, 1); 2131210312Sjmallett *data32 = (uint32_t) (tmp1 >> 32); 2132210312Sjmallett 2133210312Sjmallett return 0; 2134210312Sjmallett} 2135210312Sjmallett 2136210312Sjmallett/****************************************************************************/ 2137