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