]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/crypto/aesni/aesni.c
vfs: support negative entry promotion in lockless lookup
[FreeBSD/FreeBSD.git] / sys / crypto / aesni / aesni.c
1 /*-
2  * Copyright (c) 2005-2008 Pawel Jakub Dawidek <pjd@FreeBSD.org>
3  * Copyright (c) 2010 Konstantin Belousov <kib@FreeBSD.org>
4  * Copyright (c) 2014 The FreeBSD Foundation
5  * Copyright (c) 2017 Conrad Meyer <cem@FreeBSD.org>
6  * All rights reserved.
7  *
8  * Portions of this software were developed by John-Mark Gurney
9  * under sponsorship of the FreeBSD Foundation and
10  * Rubicon Communications, LLC (Netgate).
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
37 #include <sys/param.h>
38 #include <sys/bus.h>
39 #include <sys/kernel.h>
40 #include <sys/kobj.h>
41 #include <sys/libkern.h>
42 #include <sys/lock.h>
43 #include <sys/malloc.h>
44 #include <sys/mbuf.h>
45 #include <sys/module.h>
46 #include <sys/mutex.h>
47 #include <sys/smp.h>
48 #include <sys/systm.h>
49 #include <sys/uio.h>
50
51 #include <crypto/aesni/aesni.h>
52 #include <crypto/aesni/sha_sse.h>
53 #include <crypto/sha1.h>
54 #include <crypto/sha2/sha224.h>
55 #include <crypto/sha2/sha256.h>
56
57 #include <opencrypto/cryptodev.h>
58 #include <opencrypto/gmac.h>
59 #include <cryptodev_if.h>
60
61 #include <machine/md_var.h>
62 #include <machine/specialreg.h>
63 #if defined(__i386__)
64 #include <machine/npx.h>
65 #elif defined(__amd64__)
66 #include <machine/fpu.h>
67 #endif
68
69 static struct mtx_padalign *ctx_mtx;
70 static struct fpu_kern_ctx **ctx_fpu;
71
72 struct aesni_softc {
73         int32_t cid;
74         bool    has_aes;
75         bool    has_sha;
76 };
77
78 #define ACQUIRE_CTX(i, ctx)                                     \
79         do {                                                    \
80                 (i) = PCPU_GET(cpuid);                          \
81                 mtx_lock(&ctx_mtx[(i)]);                        \
82                 (ctx) = ctx_fpu[(i)];                           \
83         } while (0)
84 #define RELEASE_CTX(i, ctx)                                     \
85         do {                                                    \
86                 mtx_unlock(&ctx_mtx[(i)]);                      \
87                 (i) = -1;                                       \
88                 (ctx) = NULL;                                   \
89         } while (0)
90
91 static int aesni_cipher_setup(struct aesni_session *ses,
92     const struct crypto_session_params *csp);
93 static int aesni_cipher_process(struct aesni_session *ses, struct cryptop *crp);
94 static int aesni_cipher_crypt(struct aesni_session *ses, struct cryptop *crp,
95     const struct crypto_session_params *csp);
96 static int aesni_cipher_mac(struct aesni_session *ses, struct cryptop *crp,
97     const struct crypto_session_params *csp);
98
99 MALLOC_DEFINE(M_AESNI, "aesni_data", "AESNI Data");
100
101 static void
102 aesni_identify(driver_t *drv, device_t parent)
103 {
104
105         /* NB: order 10 is so we get attached after h/w devices */
106         if (device_find_child(parent, "aesni", -1) == NULL &&
107             BUS_ADD_CHILD(parent, 10, "aesni", -1) == 0)
108                 panic("aesni: could not attach");
109 }
110
111 static void
112 detect_cpu_features(bool *has_aes, bool *has_sha)
113 {
114
115         *has_aes = ((cpu_feature2 & CPUID2_AESNI) != 0 &&
116             (cpu_feature2 & CPUID2_SSE41) != 0);
117         *has_sha = ((cpu_stdext_feature & CPUID_STDEXT_SHA) != 0 &&
118             (cpu_feature2 & CPUID2_SSSE3) != 0);
119 }
120
121 static int
122 aesni_probe(device_t dev)
123 {
124         bool has_aes, has_sha;
125
126         detect_cpu_features(&has_aes, &has_sha);
127         if (!has_aes && !has_sha) {
128                 device_printf(dev, "No AES or SHA support.\n");
129                 return (EINVAL);
130         } else if (has_aes && has_sha)
131                 device_set_desc(dev,
132                     "AES-CBC,AES-CCM,AES-GCM,AES-ICM,AES-XTS,SHA1,SHA256");
133         else if (has_aes)
134                 device_set_desc(dev,
135                     "AES-CBC,AES-CCM,AES-GCM,AES-ICM,AES-XTS");
136         else
137                 device_set_desc(dev, "SHA1,SHA256");
138
139         return (0);
140 }
141
142 static void
143 aesni_cleanctx(void)
144 {
145         int i;
146
147         /* XXX - no way to return driverid */
148         CPU_FOREACH(i) {
149                 if (ctx_fpu[i] != NULL) {
150                         mtx_destroy(&ctx_mtx[i]);
151                         fpu_kern_free_ctx(ctx_fpu[i]);
152                 }
153                 ctx_fpu[i] = NULL;
154         }
155         free(ctx_mtx, M_AESNI);
156         ctx_mtx = NULL;
157         free(ctx_fpu, M_AESNI);
158         ctx_fpu = NULL;
159 }
160
161 static int
162 aesni_attach(device_t dev)
163 {
164         struct aesni_softc *sc;
165         int i;
166
167         sc = device_get_softc(dev);
168
169         sc->cid = crypto_get_driverid(dev, sizeof(struct aesni_session),
170             CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC |
171             CRYPTOCAP_F_ACCEL_SOFTWARE);
172         if (sc->cid < 0) {
173                 device_printf(dev, "Could not get crypto driver id.\n");
174                 return (ENOMEM);
175         }
176
177         ctx_mtx = malloc(sizeof *ctx_mtx * (mp_maxid + 1), M_AESNI,
178             M_WAITOK|M_ZERO);
179         ctx_fpu = malloc(sizeof *ctx_fpu * (mp_maxid + 1), M_AESNI,
180             M_WAITOK|M_ZERO);
181
182         CPU_FOREACH(i) {
183 #ifdef __amd64__
184                 ctx_fpu[i] = fpu_kern_alloc_ctx_domain(
185                     pcpu_find(i)->pc_domain, FPU_KERN_NORMAL);
186 #else
187                 ctx_fpu[i] = fpu_kern_alloc_ctx(FPU_KERN_NORMAL);
188 #endif
189                 mtx_init(&ctx_mtx[i], "anifpumtx", NULL, MTX_DEF|MTX_NEW);
190         }
191
192         detect_cpu_features(&sc->has_aes, &sc->has_sha);
193         return (0);
194 }
195
196 static int
197 aesni_detach(device_t dev)
198 {
199         struct aesni_softc *sc;
200
201         sc = device_get_softc(dev);
202
203         crypto_unregister_all(sc->cid);
204
205         aesni_cleanctx();
206
207         return (0);
208 }
209
210 static bool
211 aesni_auth_supported(struct aesni_softc *sc,
212     const struct crypto_session_params *csp)
213 {
214
215         if (!sc->has_sha)
216                 return (false);
217
218         switch (csp->csp_auth_alg) {
219         case CRYPTO_SHA1:
220         case CRYPTO_SHA2_224:
221         case CRYPTO_SHA2_256:
222         case CRYPTO_SHA1_HMAC:
223         case CRYPTO_SHA2_224_HMAC:
224         case CRYPTO_SHA2_256_HMAC:
225                 break;
226         default:
227                 return (false);
228         }
229
230         return (true);
231 }
232
233 static bool
234 aesni_cipher_supported(struct aesni_softc *sc,
235     const struct crypto_session_params *csp)
236 {
237
238         if (!sc->has_aes)
239                 return (false);
240
241         switch (csp->csp_cipher_alg) {
242         case CRYPTO_AES_CBC:
243         case CRYPTO_AES_ICM:
244                 if (csp->csp_ivlen != AES_BLOCK_LEN)
245                         return (false);
246                 return (sc->has_aes);
247         case CRYPTO_AES_XTS:
248                 if (csp->csp_ivlen != AES_XTS_IV_LEN)
249                         return (false);
250                 return (sc->has_aes);
251         default:
252                 return (false);
253         }
254 }
255
256 static int
257 aesni_probesession(device_t dev, const struct crypto_session_params *csp)
258 {
259         struct aesni_softc *sc;
260
261         sc = device_get_softc(dev);
262         if ((csp->csp_flags & ~(CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD)) !=
263             0)
264                 return (EINVAL);
265         switch (csp->csp_mode) {
266         case CSP_MODE_DIGEST:
267                 if (!aesni_auth_supported(sc, csp))
268                         return (EINVAL);
269                 break;
270         case CSP_MODE_CIPHER:
271                 if (!aesni_cipher_supported(sc, csp))
272                         return (EINVAL);
273                 break;
274         case CSP_MODE_AEAD:
275                 switch (csp->csp_cipher_alg) {
276                 case CRYPTO_AES_NIST_GCM_16:
277                         if (csp->csp_auth_mlen != 0 &&
278                             csp->csp_auth_mlen != GMAC_DIGEST_LEN)
279                                 return (EINVAL);
280                         if (csp->csp_ivlen != AES_GCM_IV_LEN ||
281                             !sc->has_aes)
282                                 return (EINVAL);
283                         break;
284                 case CRYPTO_AES_CCM_16:
285                         if (csp->csp_auth_mlen != 0 &&
286                             csp->csp_auth_mlen != AES_CBC_MAC_HASH_LEN)
287                                 return (EINVAL);
288                         if (csp->csp_ivlen != AES_CCM_IV_LEN ||
289                             !sc->has_aes)
290                                 return (EINVAL);
291                         break;
292                 default:
293                         return (EINVAL);
294                 }
295                 break;
296         case CSP_MODE_ETA:
297                 if (!aesni_auth_supported(sc, csp) ||
298                     !aesni_cipher_supported(sc, csp))
299                         return (EINVAL);
300                 break;
301         default:
302                 return (EINVAL);
303         }
304
305         return (CRYPTODEV_PROBE_ACCEL_SOFTWARE);
306 }
307
308 static int
309 aesni_newsession(device_t dev, crypto_session_t cses,
310     const struct crypto_session_params *csp)
311 {
312         struct aesni_softc *sc;
313         struct aesni_session *ses;
314         int error;
315
316         sc = device_get_softc(dev);
317
318         ses = crypto_get_driver_session(cses);
319
320         switch (csp->csp_mode) {
321         case CSP_MODE_DIGEST:
322         case CSP_MODE_CIPHER:
323         case CSP_MODE_AEAD:
324         case CSP_MODE_ETA:
325                 break;
326         default:
327                 return (EINVAL);
328         }
329         error = aesni_cipher_setup(ses, csp);
330         if (error != 0) {
331                 CRYPTDEB("setup failed");
332                 return (error);
333         }
334
335         return (0);
336 }
337
338 static int
339 aesni_process(device_t dev, struct cryptop *crp, int hint __unused)
340 {
341         struct aesni_session *ses;
342         int error;
343
344         ses = crypto_get_driver_session(crp->crp_session);
345
346         error = aesni_cipher_process(ses, crp);
347
348         crp->crp_etype = error;
349         crypto_done(crp);
350         return (0);
351 }
352
353 static uint8_t *
354 aesni_cipher_alloc(struct cryptop *crp, int start, int length, bool *allocated)
355 {
356         uint8_t *addr;
357
358         addr = crypto_contiguous_subsegment(crp, start, length);
359         if (addr != NULL) {
360                 *allocated = false;
361                 return (addr);
362         }
363         addr = malloc(length, M_AESNI, M_NOWAIT);
364         if (addr != NULL) {
365                 *allocated = true;
366                 crypto_copydata(crp, start, length, addr);
367         } else
368                 *allocated = false;
369         return (addr);
370 }
371
372 static device_method_t aesni_methods[] = {
373         DEVMETHOD(device_identify, aesni_identify),
374         DEVMETHOD(device_probe, aesni_probe),
375         DEVMETHOD(device_attach, aesni_attach),
376         DEVMETHOD(device_detach, aesni_detach),
377
378         DEVMETHOD(cryptodev_probesession, aesni_probesession),
379         DEVMETHOD(cryptodev_newsession, aesni_newsession),
380         DEVMETHOD(cryptodev_process, aesni_process),
381
382         DEVMETHOD_END
383 };
384
385 static driver_t aesni_driver = {
386         "aesni",
387         aesni_methods,
388         sizeof(struct aesni_softc),
389 };
390 static devclass_t aesni_devclass;
391
392 DRIVER_MODULE(aesni, nexus, aesni_driver, aesni_devclass, 0, 0);
393 MODULE_VERSION(aesni, 1);
394 MODULE_DEPEND(aesni, crypto, 1, 1, 1);
395
396 static int
397 intel_sha1_update(void *vctx, const void *vdata, u_int datalen)
398 {
399         struct sha1_ctxt *ctx = vctx;
400         const char *data = vdata;
401         size_t gaplen;
402         size_t gapstart;
403         size_t off;
404         size_t copysiz;
405         u_int blocks;
406
407         off = 0;
408         /* Do any aligned blocks without redundant copying. */
409         if (datalen >= 64 && ctx->count % 64 == 0) {
410                 blocks = datalen / 64;
411                 ctx->c.b64[0] += blocks * 64 * 8;
412                 intel_sha1_step(ctx->h.b32, data + off, blocks);
413                 off += blocks * 64;
414         }
415
416         while (off < datalen) {
417                 gapstart = ctx->count % 64;
418                 gaplen = 64 - gapstart;
419
420                 copysiz = (gaplen < datalen - off) ? gaplen : datalen - off;
421                 bcopy(&data[off], &ctx->m.b8[gapstart], copysiz);
422                 ctx->count += copysiz;
423                 ctx->count %= 64;
424                 ctx->c.b64[0] += copysiz * 8;
425                 if (ctx->count % 64 == 0)
426                         intel_sha1_step(ctx->h.b32, (void *)ctx->m.b8, 1);
427                 off += copysiz;
428         }
429
430         return (0);
431 }
432
433 static void
434 SHA1_Init_fn(void *ctx)
435 {
436         sha1_init(ctx);
437 }
438
439 static void
440 SHA1_Finalize_fn(void *digest, void *ctx)
441 {
442         sha1_result(ctx, digest);
443 }
444
445 static int
446 intel_sha256_update(void *vctx, const void *vdata, u_int len)
447 {
448         SHA256_CTX *ctx = vctx;
449         uint64_t bitlen;
450         uint32_t r;
451         u_int blocks;
452         const unsigned char *src = vdata;
453
454         /* Number of bytes left in the buffer from previous updates */
455         r = (ctx->count >> 3) & 0x3f;
456
457         /* Convert the length into a number of bits */
458         bitlen = len << 3;
459
460         /* Update number of bits */
461         ctx->count += bitlen;
462
463         /* Handle the case where we don't need to perform any transforms */
464         if (len < 64 - r) {
465                 memcpy(&ctx->buf[r], src, len);
466                 return (0);
467         }
468
469         /* Finish the current block */
470         memcpy(&ctx->buf[r], src, 64 - r);
471         intel_sha256_step(ctx->state, ctx->buf, 1);
472         src += 64 - r;
473         len -= 64 - r;
474
475         /* Perform complete blocks */
476         if (len >= 64) {
477                 blocks = len / 64;
478                 intel_sha256_step(ctx->state, src, blocks);
479                 src += blocks * 64;
480                 len -= blocks * 64;
481         }
482
483         /* Copy left over data into buffer */
484         memcpy(ctx->buf, src, len);
485
486         return (0);
487 }
488
489 static void
490 SHA224_Init_fn(void *ctx)
491 {
492         SHA224_Init(ctx);
493 }
494
495 static void
496 SHA224_Finalize_fn(void *digest, void *ctx)
497 {
498         SHA224_Final(digest, ctx);
499 }
500
501 static void
502 SHA256_Init_fn(void *ctx)
503 {
504         SHA256_Init(ctx);
505 }
506
507 static void
508 SHA256_Finalize_fn(void *digest, void *ctx)
509 {
510         SHA256_Final(digest, ctx);
511 }
512
513 static int
514 aesni_authprepare(struct aesni_session *ses, int klen)
515 {
516
517         if (klen > SHA1_BLOCK_LEN)
518                 return (EINVAL);
519         if ((ses->hmac && klen == 0) || (!ses->hmac && klen != 0))
520                 return (EINVAL);
521         return (0);
522 }
523
524 static int
525 aesni_cipherprepare(const struct crypto_session_params *csp)
526 {
527
528         switch (csp->csp_cipher_alg) {
529         case CRYPTO_AES_ICM:
530         case CRYPTO_AES_NIST_GCM_16:
531         case CRYPTO_AES_CCM_16:
532         case CRYPTO_AES_CBC:
533                 switch (csp->csp_cipher_klen * 8) {
534                 case 128:
535                 case 192:
536                 case 256:
537                         break;
538                 default:
539                         CRYPTDEB("invalid CBC/ICM/GCM key length");
540                         return (EINVAL);
541                 }
542                 break;
543         case CRYPTO_AES_XTS:
544                 switch (csp->csp_cipher_klen * 8) {
545                 case 256:
546                 case 512:
547                         break;
548                 default:
549                         CRYPTDEB("invalid XTS key length");
550                         return (EINVAL);
551                 }
552                 break;
553         default:
554                 return (EINVAL);
555         }
556         return (0);
557 }
558
559 static int
560 aesni_cipher_setup(struct aesni_session *ses,
561     const struct crypto_session_params *csp)
562 {
563         struct fpu_kern_ctx *ctx;
564         int kt, ctxidx, error;
565
566         switch (csp->csp_auth_alg) {
567         case CRYPTO_SHA1_HMAC:
568                 ses->hmac = true;
569                 /* FALLTHROUGH */
570         case CRYPTO_SHA1:
571                 ses->hash_len = SHA1_HASH_LEN;
572                 ses->hash_init = SHA1_Init_fn;
573                 ses->hash_update = intel_sha1_update;
574                 ses->hash_finalize = SHA1_Finalize_fn;
575                 break;
576         case CRYPTO_SHA2_224_HMAC:
577                 ses->hmac = true;
578                 /* FALLTHROUGH */
579         case CRYPTO_SHA2_224:
580                 ses->hash_len = SHA2_224_HASH_LEN;
581                 ses->hash_init = SHA224_Init_fn;
582                 ses->hash_update = intel_sha256_update;
583                 ses->hash_finalize = SHA224_Finalize_fn;
584                 break;
585         case CRYPTO_SHA2_256_HMAC:
586                 ses->hmac = true;
587                 /* FALLTHROUGH */
588         case CRYPTO_SHA2_256:
589                 ses->hash_len = SHA2_256_HASH_LEN;
590                 ses->hash_init = SHA256_Init_fn;
591                 ses->hash_update = intel_sha256_update;
592                 ses->hash_finalize = SHA256_Finalize_fn;
593                 break;
594         }
595
596         if (ses->hash_len != 0) {
597                 if (csp->csp_auth_mlen == 0)
598                         ses->mlen = ses->hash_len;
599                 else
600                         ses->mlen = csp->csp_auth_mlen;
601
602                 error = aesni_authprepare(ses, csp->csp_auth_klen);
603                 if (error != 0)
604                         return (error);
605         }
606
607         error = aesni_cipherprepare(csp);
608         if (error != 0)
609                 return (error);
610
611         kt = is_fpu_kern_thread(0) || (csp->csp_cipher_alg == 0);
612         if (!kt) {
613                 ACQUIRE_CTX(ctxidx, ctx);
614                 fpu_kern_enter(curthread, ctx,
615                     FPU_KERN_NORMAL | FPU_KERN_KTHR);
616         }
617
618         error = 0;
619         if (csp->csp_cipher_key != NULL)
620                 aesni_cipher_setup_common(ses, csp, csp->csp_cipher_key,
621                     csp->csp_cipher_klen);
622
623         if (!kt) {
624                 fpu_kern_leave(curthread, ctx);
625                 RELEASE_CTX(ctxidx, ctx);
626         }
627         return (error);
628 }
629
630 static int
631 aesni_cipher_process(struct aesni_session *ses, struct cryptop *crp)
632 {
633         const struct crypto_session_params *csp;
634         struct fpu_kern_ctx *ctx;
635         int error, ctxidx;
636         bool kt;
637
638         csp = crypto_get_params(crp->crp_session);
639         switch (csp->csp_cipher_alg) {
640         case CRYPTO_AES_ICM:
641         case CRYPTO_AES_NIST_GCM_16:
642         case CRYPTO_AES_CCM_16:
643                 if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0)
644                         return (EINVAL);
645                 break;
646         case CRYPTO_AES_CBC:
647         case CRYPTO_AES_XTS:
648                 /* CBC & XTS can only handle full blocks for now */
649                 if ((crp->crp_payload_length % AES_BLOCK_LEN) != 0)
650                         return (EINVAL);
651                 break;
652         }
653
654         ctx = NULL;
655         ctxidx = 0;
656         error = 0;
657         kt = is_fpu_kern_thread(0);
658         if (!kt) {
659                 ACQUIRE_CTX(ctxidx, ctx);
660                 fpu_kern_enter(curthread, ctx,
661                     FPU_KERN_NORMAL | FPU_KERN_KTHR);
662         }
663
664         /* Do work */
665         if (csp->csp_mode == CSP_MODE_ETA) {
666                 if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
667                         error = aesni_cipher_crypt(ses, crp, csp);
668                         if (error == 0)
669                                 error = aesni_cipher_mac(ses, crp, csp);
670                 } else {
671                         error = aesni_cipher_mac(ses, crp, csp);
672                         if (error == 0)
673                                 error = aesni_cipher_crypt(ses, crp, csp);
674                 }
675         } else if (csp->csp_mode == CSP_MODE_DIGEST)
676                 error = aesni_cipher_mac(ses, crp, csp);
677         else
678                 error = aesni_cipher_crypt(ses, crp, csp);
679
680         if (!kt) {
681                 fpu_kern_leave(curthread, ctx);
682                 RELEASE_CTX(ctxidx, ctx);
683         }
684         return (error);
685 }
686
687 static int
688 aesni_cipher_crypt(struct aesni_session *ses, struct cryptop *crp,
689     const struct crypto_session_params *csp)
690 {
691         uint8_t iv[AES_BLOCK_LEN], tag[GMAC_DIGEST_LEN];
692         uint8_t *authbuf, *buf, *outbuf;
693         int error;
694         bool encflag, allocated, authallocated, outallocated, outcopy;
695
696         buf = aesni_cipher_alloc(crp, crp->crp_payload_start,
697             crp->crp_payload_length, &allocated);
698         if (buf == NULL)
699                 return (ENOMEM);
700
701         outallocated = false;
702         authallocated = false;
703         authbuf = NULL;
704         if (csp->csp_cipher_alg == CRYPTO_AES_NIST_GCM_16 ||
705             csp->csp_cipher_alg == CRYPTO_AES_CCM_16) {
706                 if (crp->crp_aad != NULL)
707                         authbuf = crp->crp_aad;
708                 else
709                         authbuf = aesni_cipher_alloc(crp, crp->crp_aad_start,
710                             crp->crp_aad_length, &authallocated);
711                 if (authbuf == NULL) {
712                         error = ENOMEM;
713                         goto out;
714                 }
715         }
716
717         if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) {
718                 outbuf = crypto_buffer_contiguous_subsegment(&crp->crp_obuf,
719                     crp->crp_payload_output_start, crp->crp_payload_length);
720                 if (outbuf == NULL) {
721                         outcopy = true;
722                         if (allocated)
723                                 outbuf = buf;
724                         else {
725                                 outbuf = malloc(crp->crp_payload_length,
726                                     M_AESNI, M_NOWAIT);
727                                 if (outbuf == NULL) {
728                                         error = ENOMEM;
729                                         goto out;
730                                 }
731                                 outallocated = true;
732                         }
733                 } else
734                         outcopy = false;
735         } else {
736                 outbuf = buf;
737                 outcopy = allocated;
738         }
739
740         error = 0;
741         encflag = CRYPTO_OP_IS_ENCRYPT(crp->crp_op);
742         if (crp->crp_cipher_key != NULL)
743                 aesni_cipher_setup_common(ses, csp, crp->crp_cipher_key,
744                     csp->csp_cipher_klen);
745
746         crypto_read_iv(crp, iv);
747
748         switch (csp->csp_cipher_alg) {
749         case CRYPTO_AES_CBC:
750                 if (encflag)
751                         aesni_encrypt_cbc(ses->rounds, ses->enc_schedule,
752                             crp->crp_payload_length, buf, outbuf, iv);
753                 else {
754                         if (buf != outbuf)
755                                 memcpy(outbuf, buf, crp->crp_payload_length);
756                         aesni_decrypt_cbc(ses->rounds, ses->dec_schedule,
757                             crp->crp_payload_length, outbuf, iv);
758                 }
759                 break;
760         case CRYPTO_AES_ICM:
761                 /* encryption & decryption are the same */
762                 aesni_encrypt_icm(ses->rounds, ses->enc_schedule,
763                     crp->crp_payload_length, buf, outbuf, iv);
764                 break;
765         case CRYPTO_AES_XTS:
766                 if (encflag)
767                         aesni_encrypt_xts(ses->rounds, ses->enc_schedule,
768                             ses->xts_schedule, crp->crp_payload_length, buf,
769                             outbuf, iv);
770                 else
771                         aesni_decrypt_xts(ses->rounds, ses->dec_schedule,
772                             ses->xts_schedule, crp->crp_payload_length, buf,
773                             outbuf, iv);
774                 break;
775         case CRYPTO_AES_NIST_GCM_16:
776                 if (encflag) {
777                         memset(tag, 0, sizeof(tag));
778                         AES_GCM_encrypt(buf, outbuf, authbuf, iv, tag,
779                             crp->crp_payload_length, crp->crp_aad_length,
780                             csp->csp_ivlen, ses->enc_schedule, ses->rounds);
781                         crypto_copyback(crp, crp->crp_digest_start, sizeof(tag),
782                             tag);
783                 } else {
784                         crypto_copydata(crp, crp->crp_digest_start, sizeof(tag),
785                             tag);
786                         if (!AES_GCM_decrypt(buf, outbuf, authbuf, iv, tag,
787                             crp->crp_payload_length, crp->crp_aad_length,
788                             csp->csp_ivlen, ses->enc_schedule, ses->rounds))
789                                 error = EBADMSG;
790                 }
791                 break;
792         case CRYPTO_AES_CCM_16:
793                 if (encflag) {
794                         memset(tag, 0, sizeof(tag));                    
795                         AES_CCM_encrypt(buf, outbuf, authbuf, iv, tag,
796                             crp->crp_payload_length, crp->crp_aad_length,
797                             csp->csp_ivlen, ses->enc_schedule, ses->rounds);
798                         crypto_copyback(crp, crp->crp_digest_start, sizeof(tag),
799                             tag);
800                 } else {
801                         crypto_copydata(crp, crp->crp_digest_start, sizeof(tag),
802                             tag);
803                         if (!AES_CCM_decrypt(buf, outbuf, authbuf, iv, tag,
804                             crp->crp_payload_length, crp->crp_aad_length,
805                             csp->csp_ivlen, ses->enc_schedule, ses->rounds))
806                                 error = EBADMSG;
807                 }
808                 break;
809         }
810         if (outcopy && error == 0)
811                 crypto_copyback(crp, CRYPTO_HAS_OUTPUT_BUFFER(crp) ?
812                     crp->crp_payload_output_start : crp->crp_payload_start,
813                     crp->crp_payload_length, outbuf);
814
815 out:
816         if (allocated)
817                 zfree(buf, M_AESNI);
818         if (authallocated)
819                 zfree(authbuf, M_AESNI);
820         if (outallocated)
821                 zfree(outbuf, M_AESNI);
822         explicit_bzero(iv, sizeof(iv));
823         explicit_bzero(tag, sizeof(tag));
824         return (error);
825 }
826
827 static int
828 aesni_cipher_mac(struct aesni_session *ses, struct cryptop *crp,
829     const struct crypto_session_params *csp)
830 {
831         union {
832                 struct SHA256Context sha2 __aligned(16);
833                 struct sha1_ctxt sha1 __aligned(16);
834         } sctx;
835         uint32_t res[SHA2_256_HASH_LEN / sizeof(uint32_t)];
836         const uint8_t *key;
837         int i, keylen;
838
839         if (crp->crp_auth_key != NULL)
840                 key = crp->crp_auth_key;
841         else
842                 key = csp->csp_auth_key;
843         keylen = csp->csp_auth_klen;
844
845         if (ses->hmac) {
846                 uint8_t hmac_key[SHA1_BLOCK_LEN] __aligned(16);
847
848                 /* Inner hash: (K ^ IPAD) || data */
849                 ses->hash_init(&sctx);
850                 for (i = 0; i < keylen; i++)
851                         hmac_key[i] = key[i] ^ HMAC_IPAD_VAL;
852                 for (i = keylen; i < sizeof(hmac_key); i++)
853                         hmac_key[i] = 0 ^ HMAC_IPAD_VAL;
854                 ses->hash_update(&sctx, hmac_key, sizeof(hmac_key));
855
856                 if (crp->crp_aad != NULL)
857                         ses->hash_update(&sctx, crp->crp_aad,
858                             crp->crp_aad_length);
859                 else
860                         crypto_apply(crp, crp->crp_aad_start,
861                             crp->crp_aad_length, ses->hash_update, &sctx);
862                 if (CRYPTO_HAS_OUTPUT_BUFFER(crp) &&
863                     CRYPTO_OP_IS_ENCRYPT(crp->crp_op))
864                         crypto_apply_buf(&crp->crp_obuf,
865                             crp->crp_payload_output_start,
866                             crp->crp_payload_length,
867                             ses->hash_update, &sctx);
868                 else
869                         crypto_apply(crp, crp->crp_payload_start,
870                             crp->crp_payload_length, ses->hash_update, &sctx);
871                 ses->hash_finalize(res, &sctx);
872
873                 /* Outer hash: (K ^ OPAD) || inner hash */
874                 ses->hash_init(&sctx);
875                 for (i = 0; i < keylen; i++)
876                         hmac_key[i] = key[i] ^ HMAC_OPAD_VAL;
877                 for (i = keylen; i < sizeof(hmac_key); i++)
878                         hmac_key[i] = 0 ^ HMAC_OPAD_VAL;
879                 ses->hash_update(&sctx, hmac_key, sizeof(hmac_key));
880                 ses->hash_update(&sctx, res, ses->hash_len);
881                 ses->hash_finalize(res, &sctx);
882                 explicit_bzero(hmac_key, sizeof(hmac_key));
883         } else {
884                 ses->hash_init(&sctx);
885
886                 if (crp->crp_aad != NULL)
887                         ses->hash_update(&sctx, crp->crp_aad,
888                             crp->crp_aad_length);
889                 else
890                         crypto_apply(crp, crp->crp_aad_start,
891                             crp->crp_aad_length, ses->hash_update, &sctx);
892                 if (CRYPTO_HAS_OUTPUT_BUFFER(crp) &&
893                     CRYPTO_OP_IS_ENCRYPT(crp->crp_op))
894                         crypto_apply_buf(&crp->crp_obuf,
895                             crp->crp_payload_output_start,
896                             crp->crp_payload_length,
897                             ses->hash_update, &sctx);
898                 else
899                         crypto_apply(crp, crp->crp_payload_start,
900                             crp->crp_payload_length,
901                             ses->hash_update, &sctx);
902
903                 ses->hash_finalize(res, &sctx);
904         }
905
906         if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {
907                 uint32_t res2[SHA2_256_HASH_LEN / sizeof(uint32_t)];
908
909                 crypto_copydata(crp, crp->crp_digest_start, ses->mlen, res2);
910                 if (timingsafe_bcmp(res, res2, ses->mlen) != 0)
911                         return (EBADMSG);
912                 explicit_bzero(res2, sizeof(res2));
913         } else
914                 crypto_copyback(crp, crp->crp_digest_start, ses->mlen, res);
915         explicit_bzero(res, sizeof(res));
916         return (0);
917 }