]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/opencrypto/cryptosoft.c
crypto: Permit variable-sized IVs for ciphers with a reinit hook.
[FreeBSD/FreeBSD.git] / sys / opencrypto / cryptosoft.c
1 /*      $OpenBSD: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $ */
2
3 /*-
4  * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
5  * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
6  *
7  * This code was written by Angelos D. Keromytis in Athens, Greece, in
8  * February 2000. Network Security Technologies Inc. (NSTI) kindly
9  * supported the development of this code.
10  *
11  * Copyright (c) 2000, 2001 Angelos D. Keromytis
12  * Copyright (c) 2014-2021 The FreeBSD Foundation
13  * All rights reserved.
14  *
15  * Portions of this software were developed by John-Mark Gurney
16  * under sponsorship of the FreeBSD Foundation and
17  * Rubicon Communications, LLC (Netgate).
18  *
19  * Portions of this software were developed by Ararat River
20  * Consulting, LLC under sponsorship of the FreeBSD Foundation.
21  *
22  * Permission to use, copy, and modify this software with or without fee
23  * is hereby granted, provided that this entire notice is included in
24  * all source code copies of any software which is or includes a copy or
25  * modification of this software.
26  *
27  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
28  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
29  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
30  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
31  * PURPOSE.
32  */
33
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/malloc.h>
40 #include <sys/mbuf.h>
41 #include <sys/module.h>
42 #include <sys/sysctl.h>
43 #include <sys/errno.h>
44 #include <sys/random.h>
45 #include <sys/kernel.h>
46 #include <sys/uio.h>
47 #include <sys/lock.h>
48 #include <sys/rwlock.h>
49 #include <sys/endian.h>
50 #include <sys/limits.h>
51 #include <sys/mutex.h>
52
53 #include <crypto/sha1.h>
54 #include <opencrypto/rmd160.h>
55
56 #include <opencrypto/cryptodev.h>
57 #include <opencrypto/xform.h>
58
59 #include <sys/kobj.h>
60 #include <sys/bus.h>
61 #include "cryptodev_if.h"
62
63 struct swcr_auth {
64         void            *sw_ictx;
65         void            *sw_octx;
66         const struct auth_hash *sw_axf;
67         uint16_t        sw_mlen;
68 };
69
70 struct swcr_encdec {
71         void            *sw_kschedule;
72         const struct enc_xform *sw_exf;
73 };
74
75 struct swcr_compdec {
76         const struct comp_algo *sw_cxf;
77 };
78
79 struct swcr_session {
80         struct mtx      swcr_lock;
81         int     (*swcr_process)(struct swcr_session *, struct cryptop *);
82
83         struct swcr_auth swcr_auth;
84         struct swcr_encdec swcr_encdec;
85         struct swcr_compdec swcr_compdec;
86 };
87
88 static  int32_t swcr_id;
89
90 static  void swcr_freesession(device_t dev, crypto_session_t cses);
91
92 /* Used for CRYPTO_NULL_CBC. */
93 static int
94 swcr_null(struct swcr_session *ses, struct cryptop *crp)
95 {
96
97         return (0);
98 }
99
100 /*
101  * Apply a symmetric encryption/decryption algorithm.
102  */
103 static int
104 swcr_encdec(struct swcr_session *ses, struct cryptop *crp)
105 {
106         unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN];
107         unsigned char *ivp, *nivp, iv2[EALG_MAX_BLOCK_LEN];
108         const struct crypto_session_params *csp;
109         const struct enc_xform *exf;
110         struct swcr_encdec *sw;
111         size_t inlen, outlen;
112         int i, blks, resid;
113         struct crypto_buffer_cursor cc_in, cc_out;
114         const unsigned char *inblk;
115         unsigned char *outblk;
116         int error;
117         bool encrypting;
118
119         error = 0;
120
121         sw = &ses->swcr_encdec;
122         exf = sw->sw_exf;
123         csp = crypto_get_params(crp->crp_session);
124
125         if (exf->native_blocksize == 0) {
126                 /* Check for non-padded data */
127                 if ((crp->crp_payload_length % exf->blocksize) != 0)
128                         return (EINVAL);
129
130                 blks = exf->blocksize;
131         } else
132                 blks = exf->native_blocksize;
133
134         if (exf == &enc_xform_aes_icm &&
135             (crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0)
136                 return (EINVAL);
137
138         if (crp->crp_cipher_key != NULL) {
139                 error = exf->setkey(sw->sw_kschedule,
140                     crp->crp_cipher_key, csp->csp_cipher_klen);
141                 if (error)
142                         return (error);
143         }
144
145         crypto_read_iv(crp, iv);
146
147         if (exf->reinit) {
148                 /*
149                  * xforms that provide a reinit method perform all IV
150                  * handling themselves.
151                  */
152                 exf->reinit(sw->sw_kschedule, iv, csp->csp_ivlen);
153         }
154
155         ivp = iv;
156
157         crypto_cursor_init(&cc_in, &crp->crp_buf);
158         crypto_cursor_advance(&cc_in, crp->crp_payload_start);
159         inblk = crypto_cursor_segment(&cc_in, &inlen);
160         if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) {
161                 crypto_cursor_init(&cc_out, &crp->crp_obuf);
162                 crypto_cursor_advance(&cc_out, crp->crp_payload_output_start);
163         } else
164                 cc_out = cc_in;
165         outblk = crypto_cursor_segment(&cc_out, &outlen);
166
167         resid = crp->crp_payload_length;
168         encrypting = CRYPTO_OP_IS_ENCRYPT(crp->crp_op);
169
170         /*
171          * Loop through encrypting blocks.  'inlen' is the remaining
172          * length of the current segment in the input buffer.
173          * 'outlen' is the remaining length of current segment in the
174          * output buffer.
175          */
176         while (resid >= blks) {
177                 /*
178                  * If the current block is not contained within the
179                  * current input/output segment, use 'blk' as a local
180                  * buffer.
181                  */
182                 if (inlen < blks) {
183                         crypto_cursor_copydata(&cc_in, blks, blk);
184                         inblk = blk;
185                 }
186                 if (outlen < blks)
187                         outblk = blk;
188
189                 /*
190                  * Ciphers without a 'reinit' hook are assumed to be
191                  * used in CBC mode where the chaining is done here.
192                  */
193                 if (exf->reinit != NULL) {
194                         if (encrypting)
195                                 exf->encrypt(sw->sw_kschedule, inblk, outblk);
196                         else
197                                 exf->decrypt(sw->sw_kschedule, inblk, outblk);
198                 } else if (encrypting) {
199                         /* XOR with previous block */
200                         for (i = 0; i < blks; i++)
201                                 outblk[i] = inblk[i] ^ ivp[i];
202
203                         exf->encrypt(sw->sw_kschedule, outblk, outblk);
204
205                         /*
206                          * Keep encrypted block for XOR'ing
207                          * with next block
208                          */
209                         memcpy(iv, outblk, blks);
210                         ivp = iv;
211                 } else {        /* decrypt */
212                         /*
213                          * Keep encrypted block for XOR'ing
214                          * with next block
215                          */
216                         nivp = (ivp == iv) ? iv2 : iv;
217                         memcpy(nivp, inblk, blks);
218
219                         exf->decrypt(sw->sw_kschedule, inblk, outblk);
220
221                         /* XOR with previous block */
222                         for (i = 0; i < blks; i++)
223                                 outblk[i] ^= ivp[i];
224
225                         ivp = nivp;
226                 }
227
228                 if (inlen < blks) {
229                         inblk = crypto_cursor_segment(&cc_in, &inlen);
230                 } else {
231                         crypto_cursor_advance(&cc_in, blks);
232                         inlen -= blks;
233                         inblk += blks;
234                 }
235
236                 if (outlen < blks) {
237                         crypto_cursor_copyback(&cc_out, blks, blk);
238                         outblk = crypto_cursor_segment(&cc_out, &outlen);
239                 } else {
240                         crypto_cursor_advance(&cc_out, blks);
241                         outlen -= blks;
242                         outblk += blks;
243                 }
244
245                 resid -= blks;
246         }
247
248         /* Handle trailing partial block for stream ciphers. */
249         if (resid > 0) {
250                 KASSERT(exf->native_blocksize != 0,
251                     ("%s: partial block of %d bytes for cipher %s",
252                     __func__, i, exf->name));
253                 KASSERT(exf->reinit != NULL,
254                     ("%s: partial block cipher %s without reinit hook",
255                     __func__, exf->name));
256                 KASSERT(resid < blks, ("%s: partial block too big", __func__));
257
258                 inblk = crypto_cursor_segment(&cc_in, &inlen);
259                 outblk = crypto_cursor_segment(&cc_out, &outlen);
260                 if (inlen < resid) {
261                         crypto_cursor_copydata(&cc_in, resid, blk);
262                         inblk = blk;
263                 }
264                 if (outlen < resid)
265                         outblk = blk;
266                 if (encrypting)
267                         exf->encrypt_last(sw->sw_kschedule, inblk, outblk,
268                             resid);
269                 else
270                         exf->decrypt_last(sw->sw_kschedule, inblk, outblk,
271                             resid);
272                 if (outlen < resid)
273                         crypto_cursor_copyback(&cc_out, resid, blk);
274         }
275
276         explicit_bzero(blk, sizeof(blk));
277         explicit_bzero(iv, sizeof(iv));
278         explicit_bzero(iv2, sizeof(iv2));
279         return (0);
280 }
281
282 static void
283 swcr_authprepare(const struct auth_hash *axf, struct swcr_auth *sw,
284     const uint8_t *key, int klen)
285 {
286
287         switch (axf->type) {
288         case CRYPTO_SHA1_HMAC:
289         case CRYPTO_SHA2_224_HMAC:
290         case CRYPTO_SHA2_256_HMAC:
291         case CRYPTO_SHA2_384_HMAC:
292         case CRYPTO_SHA2_512_HMAC:
293         case CRYPTO_NULL_HMAC:
294         case CRYPTO_RIPEMD160_HMAC:
295                 hmac_init_ipad(axf, key, klen, sw->sw_ictx);
296                 hmac_init_opad(axf, key, klen, sw->sw_octx);
297                 break;
298         case CRYPTO_POLY1305:
299         case CRYPTO_BLAKE2B:
300         case CRYPTO_BLAKE2S:
301                 axf->Setkey(sw->sw_ictx, key, klen);
302                 axf->Init(sw->sw_ictx);
303                 break;
304         default:
305                 panic("%s: algorithm %d doesn't use keys", __func__, axf->type);
306         }
307 }
308
309 /*
310  * Compute or verify hash.
311  */
312 static int
313 swcr_authcompute(struct swcr_session *ses, struct cryptop *crp)
314 {
315         u_char aalg[HASH_MAX_LEN];
316         const struct crypto_session_params *csp;
317         struct swcr_auth *sw;
318         const struct auth_hash *axf;
319         union authctx ctx;
320         int err;
321
322         sw = &ses->swcr_auth;
323
324         axf = sw->sw_axf;
325
326         csp = crypto_get_params(crp->crp_session);
327         if (crp->crp_auth_key != NULL) {
328                 swcr_authprepare(axf, sw, crp->crp_auth_key,
329                     csp->csp_auth_klen);
330         }
331
332         bcopy(sw->sw_ictx, &ctx, axf->ctxsize);
333
334         if (crp->crp_aad != NULL)
335                 err = axf->Update(&ctx, crp->crp_aad, crp->crp_aad_length);
336         else
337                 err = crypto_apply(crp, crp->crp_aad_start, crp->crp_aad_length,
338                     axf->Update, &ctx);
339         if (err)
340                 goto out;
341
342         if (CRYPTO_HAS_OUTPUT_BUFFER(crp) &&
343             CRYPTO_OP_IS_ENCRYPT(crp->crp_op))
344                 err = crypto_apply_buf(&crp->crp_obuf,
345                     crp->crp_payload_output_start, crp->crp_payload_length,
346                     axf->Update, &ctx);
347         else
348                 err = crypto_apply(crp, crp->crp_payload_start,
349                     crp->crp_payload_length, axf->Update, &ctx);
350         if (err)
351                 goto out;
352
353         if (csp->csp_flags & CSP_F_ESN)
354                 axf->Update(&ctx, crp->crp_esn, 4);
355
356         axf->Final(aalg, &ctx);
357         if (sw->sw_octx != NULL) {
358                 bcopy(sw->sw_octx, &ctx, axf->ctxsize);
359                 axf->Update(&ctx, aalg, axf->hashsize);
360                 axf->Final(aalg, &ctx);
361         }
362
363         if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {
364                 u_char uaalg[HASH_MAX_LEN];
365
366                 crypto_copydata(crp, crp->crp_digest_start, sw->sw_mlen, uaalg);
367                 if (timingsafe_bcmp(aalg, uaalg, sw->sw_mlen) != 0)
368                         err = EBADMSG;
369                 explicit_bzero(uaalg, sizeof(uaalg));
370         } else {
371                 /* Inject the authentication data */
372                 crypto_copyback(crp, crp->crp_digest_start, sw->sw_mlen, aalg);
373         }
374         explicit_bzero(aalg, sizeof(aalg));
375 out:
376         explicit_bzero(&ctx, sizeof(ctx));
377         return (err);
378 }
379
380 CTASSERT(INT_MAX <= (1ll<<39) - 256);   /* GCM: plain text < 2^39-256 */
381 CTASSERT(INT_MAX <= (uint64_t)-1);      /* GCM: associated data <= 2^64-1 */
382
383 static int
384 swcr_gmac(struct swcr_session *ses, struct cryptop *crp)
385 {
386         uint32_t blkbuf[howmany(AES_BLOCK_LEN, sizeof(uint32_t))];
387         u_char *blk = (u_char *)blkbuf;
388         u_char tag[GMAC_DIGEST_LEN];
389         u_char iv[AES_BLOCK_LEN];
390         struct crypto_buffer_cursor cc;
391         const u_char *inblk;
392         union authctx ctx;
393         struct swcr_auth *swa;
394         const struct auth_hash *axf;
395         uint32_t *blkp;
396         size_t len;
397         int blksz, error, ivlen, resid;
398
399         swa = &ses->swcr_auth;
400         axf = swa->sw_axf;
401
402         bcopy(swa->sw_ictx, &ctx, axf->ctxsize);
403         blksz = GMAC_BLOCK_LEN;
404         KASSERT(axf->blocksize == blksz, ("%s: axf block size mismatch",
405             __func__));
406
407         /* Initialize the IV */
408         ivlen = AES_GCM_IV_LEN;
409         crypto_read_iv(crp, iv);
410
411         axf->Reinit(&ctx, iv, ivlen);
412         crypto_cursor_init(&cc, &crp->crp_buf);
413         crypto_cursor_advance(&cc, crp->crp_payload_start);
414         for (resid = crp->crp_payload_length; resid >= blksz; resid -= len) {
415                 inblk = crypto_cursor_segment(&cc, &len);
416                 if (len >= blksz) {
417                         len = rounddown(MIN(len, resid), blksz);
418                         crypto_cursor_advance(&cc, len);
419                 } else {
420                         len = blksz;
421                         crypto_cursor_copydata(&cc, len, blk);
422                         inblk = blk;
423                 }
424                 axf->Update(&ctx, inblk, len);
425         }
426         if (resid > 0) {
427                 memset(blk, 0, blksz);
428                 crypto_cursor_copydata(&cc, resid, blk);
429                 axf->Update(&ctx, blk, blksz);
430         }
431
432         /* length block */
433         memset(blk, 0, blksz);
434         blkp = (uint32_t *)blk + 1;
435         *blkp = htobe32(crp->crp_payload_length * 8);
436         axf->Update(&ctx, blk, blksz);
437
438         /* Finalize MAC */
439         axf->Final(tag, &ctx);
440
441         error = 0;
442         if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {
443                 u_char tag2[GMAC_DIGEST_LEN];
444
445                 crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen,
446                     tag2);
447                 if (timingsafe_bcmp(tag, tag2, swa->sw_mlen) != 0)
448                         error = EBADMSG;
449                 explicit_bzero(tag2, sizeof(tag2));
450         } else {
451                 /* Inject the authentication data */
452                 crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag);
453         }
454         explicit_bzero(blkbuf, sizeof(blkbuf));
455         explicit_bzero(tag, sizeof(tag));
456         explicit_bzero(iv, sizeof(iv));
457         return (error);
458 }
459
460 static int
461 swcr_gcm(struct swcr_session *ses, struct cryptop *crp)
462 {
463         uint32_t blkbuf[howmany(AES_BLOCK_LEN, sizeof(uint32_t))];
464         u_char *blk = (u_char *)blkbuf;
465         u_char tag[GMAC_DIGEST_LEN];
466         u_char iv[AES_BLOCK_LEN];
467         struct crypto_buffer_cursor cc_in, cc_out;
468         const u_char *inblk;
469         u_char *outblk;
470         union authctx ctx;
471         struct swcr_auth *swa;
472         struct swcr_encdec *swe;
473         const struct auth_hash *axf;
474         const struct enc_xform *exf;
475         uint32_t *blkp;
476         size_t len;
477         int blksz, error, ivlen, r, resid;
478
479         swa = &ses->swcr_auth;
480         axf = swa->sw_axf;
481
482         bcopy(swa->sw_ictx, &ctx, axf->ctxsize);
483         blksz = GMAC_BLOCK_LEN;
484         KASSERT(axf->blocksize == blksz, ("%s: axf block size mismatch",
485             __func__));
486
487         swe = &ses->swcr_encdec;
488         exf = swe->sw_exf;
489         KASSERT(axf->blocksize == exf->native_blocksize,
490             ("%s: blocksize mismatch", __func__));
491
492         if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0)
493                 return (EINVAL);
494
495         /* Initialize the IV */
496         ivlen = AES_GCM_IV_LEN;
497         bcopy(crp->crp_iv, iv, ivlen);
498
499         /* Supply MAC with IV */
500         axf->Reinit(&ctx, iv, ivlen);
501
502         /* Supply MAC with AAD */
503         if (crp->crp_aad != NULL) {
504                 len = rounddown(crp->crp_aad_length, blksz);
505                 if (len != 0)
506                         axf->Update(&ctx, crp->crp_aad, len);
507                 if (crp->crp_aad_length != len) {
508                         memset(blk, 0, blksz);
509                         memcpy(blk, (char *)crp->crp_aad + len,
510                             crp->crp_aad_length - len);
511                         axf->Update(&ctx, blk, blksz);
512                 }
513         } else {
514                 crypto_cursor_init(&cc_in, &crp->crp_buf);
515                 crypto_cursor_advance(&cc_in, crp->crp_aad_start);
516                 for (resid = crp->crp_aad_length; resid >= blksz;
517                      resid -= len) {
518                         inblk = crypto_cursor_segment(&cc_in, &len);
519                         if (len >= blksz) {
520                                 len = rounddown(MIN(len, resid), blksz);
521                                 crypto_cursor_advance(&cc_in, len);
522                         } else {
523                                 len = blksz;
524                                 crypto_cursor_copydata(&cc_in, len, blk);
525                                 inblk = blk;
526                         }
527                         axf->Update(&ctx, inblk, len);
528                 }
529                 if (resid > 0) {
530                         memset(blk, 0, blksz);
531                         crypto_cursor_copydata(&cc_in, resid, blk);
532                         axf->Update(&ctx, blk, blksz);
533                 }
534         }
535
536         if (crp->crp_cipher_key != NULL)
537                 exf->setkey(swe->sw_kschedule, crp->crp_cipher_key,
538                     crypto_get_params(crp->crp_session)->csp_cipher_klen);
539         exf->reinit(swe->sw_kschedule, iv, ivlen);
540
541         /* Do encryption with MAC */
542         crypto_cursor_init(&cc_in, &crp->crp_buf);
543         crypto_cursor_advance(&cc_in, crp->crp_payload_start);
544         if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) {
545                 crypto_cursor_init(&cc_out, &crp->crp_obuf);
546                 crypto_cursor_advance(&cc_out, crp->crp_payload_output_start);
547         } else
548                 cc_out = cc_in;
549         for (resid = crp->crp_payload_length; resid >= blksz; resid -= blksz) {
550                 inblk = crypto_cursor_segment(&cc_in, &len);
551                 if (len < blksz) {
552                         crypto_cursor_copydata(&cc_in, blksz, blk);
553                         inblk = blk;
554                 } else {
555                         crypto_cursor_advance(&cc_in, blksz);
556                 }
557                 if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
558                         outblk = crypto_cursor_segment(&cc_out, &len);
559                         if (len < blksz)
560                                 outblk = blk;
561                         exf->encrypt(swe->sw_kschedule, inblk, outblk);
562                         axf->Update(&ctx, outblk, blksz);
563                         if (outblk == blk)
564                                 crypto_cursor_copyback(&cc_out, blksz, blk);
565                         else
566                                 crypto_cursor_advance(&cc_out, blksz);
567                 } else {
568                         axf->Update(&ctx, inblk, blksz);
569                 }
570         }
571         if (resid > 0) {
572                 crypto_cursor_copydata(&cc_in, resid, blk);
573                 if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
574                         exf->encrypt_last(swe->sw_kschedule, blk, blk, resid);
575                         crypto_cursor_copyback(&cc_out, resid, blk);
576                 }
577                 axf->Update(&ctx, blk, resid);
578         }
579
580         /* length block */
581         memset(blk, 0, blksz);
582         blkp = (uint32_t *)blk + 1;
583         *blkp = htobe32(crp->crp_aad_length * 8);
584         blkp = (uint32_t *)blk + 3;
585         *blkp = htobe32(crp->crp_payload_length * 8);
586         axf->Update(&ctx, blk, blksz);
587
588         /* Finalize MAC */
589         axf->Final(tag, &ctx);
590
591         /* Validate tag */
592         error = 0;
593         if (!CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
594                 u_char tag2[GMAC_DIGEST_LEN];
595
596                 crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen, tag2);
597
598                 r = timingsafe_bcmp(tag, tag2, swa->sw_mlen);
599                 explicit_bzero(tag2, sizeof(tag2));
600                 if (r != 0) {
601                         error = EBADMSG;
602                         goto out;
603                 }
604
605                 /* tag matches, decrypt data */
606                 crypto_cursor_init(&cc_in, &crp->crp_buf);
607                 crypto_cursor_advance(&cc_in, crp->crp_payload_start);
608                 for (resid = crp->crp_payload_length; resid > blksz;
609                      resid -= blksz) {
610                         inblk = crypto_cursor_segment(&cc_in, &len);
611                         if (len < blksz) {
612                                 crypto_cursor_copydata(&cc_in, blksz, blk);
613                                 inblk = blk;
614                         } else
615                                 crypto_cursor_advance(&cc_in, blksz);
616                         outblk = crypto_cursor_segment(&cc_out, &len);
617                         if (len < blksz)
618                                 outblk = blk;
619                         exf->decrypt(swe->sw_kschedule, inblk, outblk);
620                         if (outblk == blk)
621                                 crypto_cursor_copyback(&cc_out, blksz, blk);
622                         else
623                                 crypto_cursor_advance(&cc_out, blksz);
624                 }
625                 if (resid > 0) {
626                         crypto_cursor_copydata(&cc_in, resid, blk);
627                         exf->decrypt_last(swe->sw_kschedule, blk, blk, resid);
628                         crypto_cursor_copyback(&cc_out, resid, blk);
629                 }
630         } else {
631                 /* Inject the authentication data */
632                 crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag);
633         }
634
635 out:
636         explicit_bzero(blkbuf, sizeof(blkbuf));
637         explicit_bzero(tag, sizeof(tag));
638         explicit_bzero(iv, sizeof(iv));
639
640         return (error);
641 }
642
643 static int
644 swcr_ccm_cbc_mac(struct swcr_session *ses, struct cryptop *crp)
645 {
646         u_char tag[AES_CBC_MAC_HASH_LEN];
647         u_char iv[AES_BLOCK_LEN];
648         union authctx ctx;
649         struct swcr_auth *swa;
650         const struct auth_hash *axf;
651         int error, ivlen;
652
653         swa = &ses->swcr_auth;
654         axf = swa->sw_axf;
655
656         bcopy(swa->sw_ictx, &ctx, axf->ctxsize);
657
658         /* Initialize the IV */
659         ivlen = AES_CCM_IV_LEN;
660         crypto_read_iv(crp, iv);
661
662         /*
663          * AES CCM-CBC-MAC needs to know the length of both the auth
664          * data and payload data before doing the auth computation.
665          */
666         ctx.aes_cbc_mac_ctx.authDataLength = crp->crp_payload_length;
667         ctx.aes_cbc_mac_ctx.cryptDataLength = 0;
668
669         axf->Reinit(&ctx, iv, ivlen);
670         if (crp->crp_aad != NULL)
671                 error = axf->Update(&ctx, crp->crp_aad, crp->crp_aad_length);
672         else
673                 error = crypto_apply(crp, crp->crp_payload_start,
674                     crp->crp_payload_length, axf->Update, &ctx);
675         if (error)
676                 return (error);
677
678         /* Finalize MAC */
679         axf->Final(tag, &ctx);
680
681         if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) {
682                 u_char tag2[AES_CBC_MAC_HASH_LEN];
683
684                 crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen,
685                     tag2);
686                 if (timingsafe_bcmp(tag, tag2, swa->sw_mlen) != 0)
687                         error = EBADMSG;
688                 explicit_bzero(tag2, sizeof(tag));
689         } else {
690                 /* Inject the authentication data */
691                 crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag);
692         }
693         explicit_bzero(tag, sizeof(tag));
694         explicit_bzero(iv, sizeof(iv));
695         return (error);
696 }
697
698 static int
699 swcr_ccm(struct swcr_session *ses, struct cryptop *crp)
700 {
701         uint32_t blkbuf[howmany(AES_BLOCK_LEN, sizeof(uint32_t))];
702         u_char *blk = (u_char *)blkbuf;
703         u_char tag[AES_CBC_MAC_HASH_LEN];
704         u_char iv[AES_BLOCK_LEN];
705         struct crypto_buffer_cursor cc_in, cc_out;
706         const u_char *inblk;
707         u_char *outblk;
708         union authctx ctx;
709         struct swcr_auth *swa;
710         struct swcr_encdec *swe;
711         const struct auth_hash *axf;
712         const struct enc_xform *exf;
713         size_t len;
714         int blksz, error, ivlen, r, resid;
715
716         swa = &ses->swcr_auth;
717         axf = swa->sw_axf;
718
719         bcopy(swa->sw_ictx, &ctx, axf->ctxsize);
720         blksz = AES_BLOCK_LEN;
721         KASSERT(axf->blocksize == blksz, ("%s: axf block size mismatch",
722             __func__));
723
724         swe = &ses->swcr_encdec;
725         exf = swe->sw_exf;
726         KASSERT(axf->blocksize == exf->native_blocksize,
727             ("%s: blocksize mismatch", __func__));
728
729         if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0)
730                 return (EINVAL);
731
732         /* Initialize the IV */
733         ivlen = AES_CCM_IV_LEN;
734         bcopy(crp->crp_iv, iv, ivlen);
735
736         /*
737          * AES CCM-CBC-MAC needs to know the length of both the auth
738          * data and payload data before doing the auth computation.
739          */
740         ctx.aes_cbc_mac_ctx.authDataLength = crp->crp_aad_length;
741         ctx.aes_cbc_mac_ctx.cryptDataLength = crp->crp_payload_length;
742
743         /* Supply MAC with IV */
744         axf->Reinit(&ctx, iv, ivlen);
745
746         /* Supply MAC with AAD */
747         if (crp->crp_aad != NULL)
748                 error = axf->Update(&ctx, crp->crp_aad, crp->crp_aad_length);
749         else
750                 error = crypto_apply(crp, crp->crp_aad_start,
751                     crp->crp_aad_length, axf->Update, &ctx);
752         if (error)
753                 return (error);
754
755         if (crp->crp_cipher_key != NULL)
756                 exf->setkey(swe->sw_kschedule, crp->crp_cipher_key,
757                     crypto_get_params(crp->crp_session)->csp_cipher_klen);
758         exf->reinit(swe->sw_kschedule, iv, ivlen);
759
760         /* Do encryption/decryption with MAC */
761         crypto_cursor_init(&cc_in, &crp->crp_buf);
762         crypto_cursor_advance(&cc_in, crp->crp_payload_start);
763         if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) {
764                 crypto_cursor_init(&cc_out, &crp->crp_obuf);
765                 crypto_cursor_advance(&cc_out, crp->crp_payload_output_start);
766         } else
767                 cc_out = cc_in;
768         for (resid = crp->crp_payload_length; resid >= blksz; resid -= blksz) {
769                 inblk = crypto_cursor_segment(&cc_in, &len);
770                 if (len < blksz) {
771                         crypto_cursor_copydata(&cc_in, blksz, blk);
772                         inblk = blk;
773                 } else
774                         crypto_cursor_advance(&cc_in, blksz);
775                 if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
776                         outblk = crypto_cursor_segment(&cc_out, &len);
777                         if (len < blksz)
778                                 outblk = blk;
779                         axf->Update(&ctx, inblk, blksz);
780                         exf->encrypt(swe->sw_kschedule, inblk, outblk);
781                         if (outblk == blk)
782                                 crypto_cursor_copyback(&cc_out, blksz, blk);
783                         else
784                                 crypto_cursor_advance(&cc_out, blksz);
785                 } else {
786                         /*
787                          * One of the problems with CCM+CBC is that
788                          * the authentication is done on the
789                          * unencrypted data.  As a result, we have to
790                          * decrypt the data twice: once to generate
791                          * the tag and a second time after the tag is
792                          * verified.
793                          */
794                         exf->decrypt(swe->sw_kschedule, inblk, blk);
795                         axf->Update(&ctx, blk, blksz);
796                 }
797         }
798         if (resid > 0) {
799                 crypto_cursor_copydata(&cc_in, resid, blk);
800                 if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
801                         axf->Update(&ctx, blk, resid);
802                         exf->encrypt_last(swe->sw_kschedule, blk, blk, resid);
803                         crypto_cursor_copyback(&cc_out, resid, blk);
804                 } else {
805                         exf->decrypt_last(swe->sw_kschedule, blk, blk, resid);
806                         axf->Update(&ctx, blk, resid);
807                 }
808         }
809
810         /* Finalize MAC */
811         axf->Final(tag, &ctx);
812
813         /* Validate tag */
814         error = 0;
815         if (!CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
816                 u_char tag2[AES_CBC_MAC_HASH_LEN];
817
818                 crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen,
819                     tag2);
820
821                 r = timingsafe_bcmp(tag, tag2, swa->sw_mlen);
822                 explicit_bzero(tag2, sizeof(tag2));
823                 if (r != 0) {
824                         error = EBADMSG;
825                         goto out;
826                 }
827
828                 /* tag matches, decrypt data */
829                 exf->reinit(swe->sw_kschedule, iv, ivlen);
830                 crypto_cursor_init(&cc_in, &crp->crp_buf);
831                 crypto_cursor_advance(&cc_in, crp->crp_payload_start);
832                 for (resid = crp->crp_payload_length; resid > blksz;
833                      resid -= blksz) {
834                         inblk = crypto_cursor_segment(&cc_in, &len);
835                         if (len < blksz) {
836                                 crypto_cursor_copydata(&cc_in, blksz, blk);
837                                 inblk = blk;
838                         } else
839                                 crypto_cursor_advance(&cc_in, blksz);
840                         outblk = crypto_cursor_segment(&cc_out, &len);
841                         if (len < blksz)
842                                 outblk = blk;
843                         exf->decrypt(swe->sw_kschedule, inblk, outblk);
844                         if (outblk == blk)
845                                 crypto_cursor_copyback(&cc_out, blksz, blk);
846                         else
847                                 crypto_cursor_advance(&cc_out, blksz);
848                 }
849                 if (resid > 0) {
850                         crypto_cursor_copydata(&cc_in, resid, blk);
851                         exf->decrypt_last(swe->sw_kschedule, blk, blk, resid);
852                         crypto_cursor_copyback(&cc_out, resid, blk);
853                 }
854         } else {
855                 /* Inject the authentication data */
856                 crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag);
857         }
858
859 out:
860         explicit_bzero(blkbuf, sizeof(blkbuf));
861         explicit_bzero(tag, sizeof(tag));
862         explicit_bzero(iv, sizeof(iv));
863         return (error);
864 }
865
866 static int
867 swcr_chacha20_poly1305(struct swcr_session *ses, struct cryptop *crp)
868 {
869         const struct crypto_session_params *csp;
870         uint64_t blkbuf[howmany(CHACHA20_NATIVE_BLOCK_LEN, sizeof(uint64_t))];
871         u_char *blk = (u_char *)blkbuf;
872         u_char tag[POLY1305_HASH_LEN];
873         struct crypto_buffer_cursor cc_in, cc_out;
874         const u_char *inblk;
875         u_char *outblk;
876         uint64_t *blkp;
877         union authctx ctx;
878         struct swcr_auth *swa;
879         struct swcr_encdec *swe;
880         const struct auth_hash *axf;
881         const struct enc_xform *exf;
882         size_t len;
883         int blksz, error, r, resid;
884
885         swa = &ses->swcr_auth;
886         axf = swa->sw_axf;
887
888         swe = &ses->swcr_encdec;
889         exf = swe->sw_exf;
890         blksz = exf->native_blocksize;
891         KASSERT(blksz <= sizeof(blkbuf), ("%s: blocksize mismatch", __func__));
892
893         if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0)
894                 return (EINVAL);
895
896         csp = crypto_get_params(crp->crp_session);
897
898         /* Generate Poly1305 key. */
899         if (crp->crp_cipher_key != NULL)
900                 axf->Setkey(&ctx, crp->crp_cipher_key, csp->csp_cipher_klen);
901         else
902                 axf->Setkey(&ctx, csp->csp_cipher_key, csp->csp_cipher_klen);
903         axf->Reinit(&ctx, crp->crp_iv, csp->csp_ivlen);
904
905         /* Supply MAC with AAD */
906         if (crp->crp_aad != NULL)
907                 axf->Update(&ctx, crp->crp_aad, crp->crp_aad_length);
908         else
909                 crypto_apply(crp, crp->crp_aad_start,
910                     crp->crp_aad_length, axf->Update, &ctx);
911         if (crp->crp_aad_length % 16 != 0) {
912                 /* padding1 */
913                 memset(blk, 0, 16);
914                 axf->Update(&ctx, blk, 16 - crp->crp_aad_length % 16);
915         }
916
917         if (crp->crp_cipher_key != NULL)
918                 exf->setkey(swe->sw_kschedule, crp->crp_cipher_key,
919                     csp->csp_cipher_klen);
920         exf->reinit(swe->sw_kschedule, crp->crp_iv, csp->csp_ivlen);
921
922         /* Do encryption with MAC */
923         crypto_cursor_init(&cc_in, &crp->crp_buf);
924         crypto_cursor_advance(&cc_in, crp->crp_payload_start);
925         if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) {
926                 crypto_cursor_init(&cc_out, &crp->crp_obuf);
927                 crypto_cursor_advance(&cc_out, crp->crp_payload_output_start);
928         } else
929                 cc_out = cc_in;
930         for (resid = crp->crp_payload_length; resid >= blksz; resid -= blksz) {
931                 inblk = crypto_cursor_segment(&cc_in, &len);
932                 if (len < blksz) {
933                         crypto_cursor_copydata(&cc_in, blksz, blk);
934                         inblk = blk;
935                 } else
936                         crypto_cursor_advance(&cc_in, blksz);
937                 if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
938                         outblk = crypto_cursor_segment(&cc_out, &len);
939                         if (len < blksz)
940                                 outblk = blk;
941                         exf->encrypt(swe->sw_kschedule, inblk, outblk);
942                         axf->Update(&ctx, outblk, blksz);
943                         if (outblk == blk)
944                                 crypto_cursor_copyback(&cc_out, blksz, blk);
945                         else
946                                 crypto_cursor_advance(&cc_out, blksz);
947                 } else {
948                         axf->Update(&ctx, inblk, blksz);
949                 }
950         }
951         if (resid > 0) {
952                 crypto_cursor_copydata(&cc_in, resid, blk);
953                 if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
954                         exf->encrypt_last(swe->sw_kschedule, blk, blk, resid);
955                         crypto_cursor_copyback(&cc_out, resid, blk);
956                 }
957                 axf->Update(&ctx, blk, resid);
958                 if (resid % 16 != 0) {
959                         /* padding2 */
960                         memset(blk, 0, 16);
961                         axf->Update(&ctx, blk, 16 - resid % 16);
962                 }
963         }
964
965         /* lengths */
966         blkp = (uint64_t *)blk;
967         blkp[0] = htole64(crp->crp_aad_length);
968         blkp[1] = htole64(crp->crp_payload_length);
969         axf->Update(&ctx, blk, sizeof(uint64_t) * 2);
970
971         /* Finalize MAC */
972         axf->Final(tag, &ctx);
973
974         /* Validate tag */
975         error = 0;
976         if (!CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
977                 u_char tag2[POLY1305_HASH_LEN];
978
979                 crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen, tag2);
980
981                 r = timingsafe_bcmp(tag, tag2, swa->sw_mlen);
982                 explicit_bzero(tag2, sizeof(tag2));
983                 if (r != 0) {
984                         error = EBADMSG;
985                         goto out;
986                 }
987
988                 /* tag matches, decrypt data */
989                 crypto_cursor_init(&cc_in, &crp->crp_buf);
990                 crypto_cursor_advance(&cc_in, crp->crp_payload_start);
991                 for (resid = crp->crp_payload_length; resid > blksz;
992                      resid -= blksz) {
993                         inblk = crypto_cursor_segment(&cc_in, &len);
994                         if (len < blksz) {
995                                 crypto_cursor_copydata(&cc_in, blksz, blk);
996                                 inblk = blk;
997                         } else
998                                 crypto_cursor_advance(&cc_in, blksz);
999                         outblk = crypto_cursor_segment(&cc_out, &len);
1000                         if (len < blksz)
1001                                 outblk = blk;
1002                         exf->decrypt(swe->sw_kschedule, inblk, outblk);
1003                         if (outblk == blk)
1004                                 crypto_cursor_copyback(&cc_out, blksz, blk);
1005                         else
1006                                 crypto_cursor_advance(&cc_out, blksz);
1007                 }
1008                 if (resid > 0) {
1009                         crypto_cursor_copydata(&cc_in, resid, blk);
1010                         exf->decrypt_last(swe->sw_kschedule, blk, blk, resid);
1011                         crypto_cursor_copyback(&cc_out, resid, blk);
1012                 }
1013         } else {
1014                 /* Inject the authentication data */
1015                 crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag);
1016         }
1017
1018 out:
1019         explicit_bzero(blkbuf, sizeof(blkbuf));
1020         explicit_bzero(tag, sizeof(tag));
1021         explicit_bzero(&ctx, sizeof(ctx));
1022         return (error);
1023 }
1024
1025 /*
1026  * Apply a cipher and a digest to perform EtA.
1027  */
1028 static int
1029 swcr_eta(struct swcr_session *ses, struct cryptop *crp)
1030 {
1031         int error;
1032
1033         if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) {
1034                 error = swcr_encdec(ses, crp);
1035                 if (error == 0)
1036                         error = swcr_authcompute(ses, crp);
1037         } else {
1038                 error = swcr_authcompute(ses, crp);
1039                 if (error == 0)
1040                         error = swcr_encdec(ses, crp);
1041         }
1042         return (error);
1043 }
1044
1045 /*
1046  * Apply a compression/decompression algorithm
1047  */
1048 static int
1049 swcr_compdec(struct swcr_session *ses, struct cryptop *crp)
1050 {
1051         const struct comp_algo *cxf;
1052         uint8_t *data, *out;
1053         int adj;
1054         uint32_t result;
1055
1056         cxf = ses->swcr_compdec.sw_cxf;
1057
1058         /* We must handle the whole buffer of data in one time
1059          * then if there is not all the data in the mbuf, we must
1060          * copy in a buffer.
1061          */
1062
1063         data = malloc(crp->crp_payload_length, M_CRYPTO_DATA,  M_NOWAIT);
1064         if (data == NULL)
1065                 return (EINVAL);
1066         crypto_copydata(crp, crp->crp_payload_start, crp->crp_payload_length,
1067             data);
1068
1069         if (CRYPTO_OP_IS_COMPRESS(crp->crp_op))
1070                 result = cxf->compress(data, crp->crp_payload_length, &out);
1071         else
1072                 result = cxf->decompress(data, crp->crp_payload_length, &out);
1073
1074         free(data, M_CRYPTO_DATA);
1075         if (result == 0)
1076                 return (EINVAL);
1077         crp->crp_olen = result;
1078
1079         /* Check the compressed size when doing compression */
1080         if (CRYPTO_OP_IS_COMPRESS(crp->crp_op)) {
1081                 if (result >= crp->crp_payload_length) {
1082                         /* Compression was useless, we lost time */
1083                         free(out, M_CRYPTO_DATA);
1084                         return (0);
1085                 }
1086         }
1087
1088         /* Copy back the (de)compressed data. m_copyback is
1089          * extending the mbuf as necessary.
1090          */
1091         crypto_copyback(crp, crp->crp_payload_start, result, out);
1092         if (result < crp->crp_payload_length) {
1093                 switch (crp->crp_buf.cb_type) {
1094                 case CRYPTO_BUF_MBUF:
1095                 case CRYPTO_BUF_SINGLE_MBUF:
1096                         adj = result - crp->crp_payload_length;
1097                         m_adj(crp->crp_buf.cb_mbuf, adj);
1098                         break;
1099                 case CRYPTO_BUF_UIO: {
1100                         struct uio *uio = crp->crp_buf.cb_uio;
1101                         int ind;
1102
1103                         adj = crp->crp_payload_length - result;
1104                         ind = uio->uio_iovcnt - 1;
1105
1106                         while (adj > 0 && ind >= 0) {
1107                                 if (adj < uio->uio_iov[ind].iov_len) {
1108                                         uio->uio_iov[ind].iov_len -= adj;
1109                                         break;
1110                                 }
1111
1112                                 adj -= uio->uio_iov[ind].iov_len;
1113                                 uio->uio_iov[ind].iov_len = 0;
1114                                 ind--;
1115                                 uio->uio_iovcnt--;
1116                         }
1117                         }
1118                         break;
1119                 case CRYPTO_BUF_VMPAGE:
1120                         adj = crp->crp_payload_length - result;
1121                         crp->crp_buf.cb_vm_page_len -= adj;
1122                         break;
1123                 default:
1124                         break;
1125                 }
1126         }
1127         free(out, M_CRYPTO_DATA);
1128         return 0;
1129 }
1130
1131 static int
1132 swcr_setup_cipher(struct swcr_session *ses,
1133     const struct crypto_session_params *csp)
1134 {
1135         struct swcr_encdec *swe;
1136         const struct enc_xform *txf;
1137         int error;
1138
1139         swe = &ses->swcr_encdec;
1140         txf = crypto_cipher(csp);
1141         MPASS(txf->ivsize == csp->csp_ivlen);
1142         if (txf->ctxsize != 0) {
1143                 swe->sw_kschedule = malloc(txf->ctxsize, M_CRYPTO_DATA,
1144                     M_NOWAIT);
1145                 if (swe->sw_kschedule == NULL)
1146                         return (ENOMEM);
1147         }
1148         if (csp->csp_cipher_key != NULL) {
1149                 error = txf->setkey(swe->sw_kschedule,
1150                     csp->csp_cipher_key, csp->csp_cipher_klen);
1151                 if (error)
1152                         return (error);
1153         }
1154         swe->sw_exf = txf;
1155         return (0);
1156 }
1157
1158 static int
1159 swcr_setup_auth(struct swcr_session *ses,
1160     const struct crypto_session_params *csp)
1161 {
1162         struct swcr_auth *swa;
1163         const struct auth_hash *axf;
1164
1165         swa = &ses->swcr_auth;
1166
1167         axf = crypto_auth_hash(csp);
1168         swa->sw_axf = axf;
1169         if (csp->csp_auth_mlen < 0 || csp->csp_auth_mlen > axf->hashsize)
1170                 return (EINVAL);
1171         if (csp->csp_auth_mlen == 0)
1172                 swa->sw_mlen = axf->hashsize;
1173         else
1174                 swa->sw_mlen = csp->csp_auth_mlen;
1175         swa->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT);
1176         if (swa->sw_ictx == NULL)
1177                 return (ENOBUFS);
1178
1179         switch (csp->csp_auth_alg) {
1180         case CRYPTO_SHA1_HMAC:
1181         case CRYPTO_SHA2_224_HMAC:
1182         case CRYPTO_SHA2_256_HMAC:
1183         case CRYPTO_SHA2_384_HMAC:
1184         case CRYPTO_SHA2_512_HMAC:
1185         case CRYPTO_NULL_HMAC:
1186         case CRYPTO_RIPEMD160_HMAC:
1187                 swa->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
1188                     M_NOWAIT);
1189                 if (swa->sw_octx == NULL)
1190                         return (ENOBUFS);
1191
1192                 if (csp->csp_auth_key != NULL) {
1193                         swcr_authprepare(axf, swa, csp->csp_auth_key,
1194                             csp->csp_auth_klen);
1195                 }
1196
1197                 if (csp->csp_mode == CSP_MODE_DIGEST)
1198                         ses->swcr_process = swcr_authcompute;
1199                 break;
1200         case CRYPTO_SHA1:
1201         case CRYPTO_SHA2_224:
1202         case CRYPTO_SHA2_256:
1203         case CRYPTO_SHA2_384:
1204         case CRYPTO_SHA2_512:
1205                 axf->Init(swa->sw_ictx);
1206                 if (csp->csp_mode == CSP_MODE_DIGEST)
1207                         ses->swcr_process = swcr_authcompute;
1208                 break;
1209         case CRYPTO_AES_NIST_GMAC:
1210                 axf->Init(swa->sw_ictx);
1211                 axf->Setkey(swa->sw_ictx, csp->csp_auth_key,
1212                     csp->csp_auth_klen);
1213                 if (csp->csp_mode == CSP_MODE_DIGEST)
1214                         ses->swcr_process = swcr_gmac;
1215                 break;
1216         case CRYPTO_POLY1305:
1217         case CRYPTO_BLAKE2B:
1218         case CRYPTO_BLAKE2S:
1219                 /*
1220                  * Blake2b and Blake2s support an optional key but do
1221                  * not require one.
1222                  */
1223                 if (csp->csp_auth_klen == 0 || csp->csp_auth_key != NULL)
1224                         axf->Setkey(swa->sw_ictx, csp->csp_auth_key,
1225                             csp->csp_auth_klen);
1226                 axf->Init(swa->sw_ictx);
1227                 if (csp->csp_mode == CSP_MODE_DIGEST)
1228                         ses->swcr_process = swcr_authcompute;
1229                 break;
1230         case CRYPTO_AES_CCM_CBC_MAC:
1231                 axf->Init(swa->sw_ictx);
1232                 axf->Setkey(swa->sw_ictx, csp->csp_auth_key,
1233                     csp->csp_auth_klen);
1234                 if (csp->csp_mode == CSP_MODE_DIGEST)
1235                         ses->swcr_process = swcr_ccm_cbc_mac;
1236                 break;
1237         }
1238
1239         return (0);
1240 }
1241
1242 static int
1243 swcr_setup_gcm(struct swcr_session *ses,
1244     const struct crypto_session_params *csp)
1245 {
1246         struct swcr_auth *swa;
1247         const struct auth_hash *axf;
1248
1249         if (csp->csp_ivlen != AES_GCM_IV_LEN)
1250                 return (EINVAL);
1251
1252         /* First, setup the auth side. */
1253         swa = &ses->swcr_auth;
1254         switch (csp->csp_cipher_klen * 8) {
1255         case 128:
1256                 axf = &auth_hash_nist_gmac_aes_128;
1257                 break;
1258         case 192:
1259                 axf = &auth_hash_nist_gmac_aes_192;
1260                 break;
1261         case 256:
1262                 axf = &auth_hash_nist_gmac_aes_256;
1263                 break;
1264         default:
1265                 return (EINVAL);
1266         }
1267         swa->sw_axf = axf;
1268         if (csp->csp_auth_mlen < 0 || csp->csp_auth_mlen > axf->hashsize)
1269                 return (EINVAL);
1270         if (csp->csp_auth_mlen == 0)
1271                 swa->sw_mlen = axf->hashsize;
1272         else
1273                 swa->sw_mlen = csp->csp_auth_mlen;
1274         swa->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT);
1275         if (swa->sw_ictx == NULL)
1276                 return (ENOBUFS);
1277         axf->Init(swa->sw_ictx);
1278         if (csp->csp_cipher_key != NULL)
1279                 axf->Setkey(swa->sw_ictx, csp->csp_cipher_key,
1280                     csp->csp_cipher_klen);
1281
1282         /* Second, setup the cipher side. */
1283         return (swcr_setup_cipher(ses, csp));
1284 }
1285
1286 static int
1287 swcr_setup_ccm(struct swcr_session *ses,
1288     const struct crypto_session_params *csp)
1289 {
1290         struct swcr_auth *swa;
1291         const struct auth_hash *axf;
1292
1293         if (csp->csp_ivlen != AES_CCM_IV_LEN)
1294                 return (EINVAL);
1295
1296         /* First, setup the auth side. */
1297         swa = &ses->swcr_auth;
1298         switch (csp->csp_cipher_klen * 8) {
1299         case 128:
1300                 axf = &auth_hash_ccm_cbc_mac_128;
1301                 break;
1302         case 192:
1303                 axf = &auth_hash_ccm_cbc_mac_192;
1304                 break;
1305         case 256:
1306                 axf = &auth_hash_ccm_cbc_mac_256;
1307                 break;
1308         default:
1309                 return (EINVAL);
1310         }
1311         swa->sw_axf = axf;
1312         if (csp->csp_auth_mlen < 0 || csp->csp_auth_mlen > axf->hashsize)
1313                 return (EINVAL);
1314         if (csp->csp_auth_mlen == 0)
1315                 swa->sw_mlen = axf->hashsize;
1316         else
1317                 swa->sw_mlen = csp->csp_auth_mlen;
1318         swa->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT);
1319         if (swa->sw_ictx == NULL)
1320                 return (ENOBUFS);
1321         axf->Init(swa->sw_ictx);
1322         if (csp->csp_cipher_key != NULL)
1323                 axf->Setkey(swa->sw_ictx, csp->csp_cipher_key,
1324                     csp->csp_cipher_klen);
1325
1326         /* Second, setup the cipher side. */
1327         return (swcr_setup_cipher(ses, csp));
1328 }
1329
1330 static int
1331 swcr_setup_chacha20_poly1305(struct swcr_session *ses,
1332     const struct crypto_session_params *csp)
1333 {
1334         struct swcr_auth *swa;
1335         const struct auth_hash *axf;
1336
1337         if (csp->csp_ivlen != CHACHA20_POLY1305_IV_LEN)
1338                 return (EINVAL);
1339
1340         /* First, setup the auth side. */
1341         swa = &ses->swcr_auth;
1342         axf = &auth_hash_chacha20_poly1305;
1343         swa->sw_axf = axf;
1344         if (csp->csp_auth_mlen < 0 || csp->csp_auth_mlen > axf->hashsize)
1345                 return (EINVAL);
1346         if (csp->csp_auth_mlen == 0)
1347                 swa->sw_mlen = axf->hashsize;
1348         else
1349                 swa->sw_mlen = csp->csp_auth_mlen;
1350
1351         /* The auth state is regenerated for each nonce. */
1352
1353         /* Second, setup the cipher side. */
1354         return (swcr_setup_cipher(ses, csp));
1355 }
1356
1357 static bool
1358 swcr_auth_supported(const struct crypto_session_params *csp)
1359 {
1360         const struct auth_hash *axf;
1361
1362         axf = crypto_auth_hash(csp);
1363         if (axf == NULL)
1364                 return (false);
1365         switch (csp->csp_auth_alg) {
1366         case CRYPTO_SHA1_HMAC:
1367         case CRYPTO_SHA2_224_HMAC:
1368         case CRYPTO_SHA2_256_HMAC:
1369         case CRYPTO_SHA2_384_HMAC:
1370         case CRYPTO_SHA2_512_HMAC:
1371         case CRYPTO_NULL_HMAC:
1372         case CRYPTO_RIPEMD160_HMAC:
1373                 break;
1374         case CRYPTO_AES_NIST_GMAC:
1375                 switch (csp->csp_auth_klen * 8) {
1376                 case 128:
1377                 case 192:
1378                 case 256:
1379                         break;
1380                 default:
1381                         return (false);
1382                 }
1383                 if (csp->csp_auth_key == NULL)
1384                         return (false);
1385                 if (csp->csp_ivlen != AES_GCM_IV_LEN)
1386                         return (false);
1387                 break;
1388         case CRYPTO_POLY1305:
1389                 if (csp->csp_auth_klen != POLY1305_KEY_LEN)
1390                         return (false);
1391                 break;
1392         case CRYPTO_AES_CCM_CBC_MAC:
1393                 switch (csp->csp_auth_klen * 8) {
1394                 case 128:
1395                 case 192:
1396                 case 256:
1397                         break;
1398                 default:
1399                         return (false);
1400                 }
1401                 if (csp->csp_auth_key == NULL)
1402                         return (false);
1403                 if (csp->csp_ivlen != AES_CCM_IV_LEN)
1404                         return (false);
1405                 break;
1406         }
1407         return (true);
1408 }
1409
1410 static bool
1411 swcr_cipher_supported(const struct crypto_session_params *csp)
1412 {
1413         const struct enc_xform *txf;
1414
1415         txf = crypto_cipher(csp);
1416         if (txf == NULL)
1417                 return (false);
1418         if (csp->csp_cipher_alg != CRYPTO_NULL_CBC &&
1419             txf->ivsize != csp->csp_ivlen)
1420                 return (false);
1421         return (true);
1422 }
1423
1424 #define SUPPORTED_SES (CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD | CSP_F_ESN)
1425
1426 static int
1427 swcr_probesession(device_t dev, const struct crypto_session_params *csp)
1428 {
1429         if ((csp->csp_flags & ~(SUPPORTED_SES)) != 0)
1430                 return (EINVAL);
1431         switch (csp->csp_mode) {
1432         case CSP_MODE_COMPRESS:
1433                 switch (csp->csp_cipher_alg) {
1434                 case CRYPTO_DEFLATE_COMP:
1435                         break;
1436                 default:
1437                         return (EINVAL);
1438                 }
1439                 break;
1440         case CSP_MODE_CIPHER:
1441                 switch (csp->csp_cipher_alg) {
1442                 case CRYPTO_AES_NIST_GCM_16:
1443                 case CRYPTO_AES_CCM_16:
1444                 case CRYPTO_CHACHA20_POLY1305:
1445                         return (EINVAL);
1446                 default:
1447                         if (!swcr_cipher_supported(csp))
1448                                 return (EINVAL);
1449                         break;
1450                 }
1451                 break;
1452         case CSP_MODE_DIGEST:
1453                 if (!swcr_auth_supported(csp))
1454                         return (EINVAL);
1455                 break;
1456         case CSP_MODE_AEAD:
1457                 switch (csp->csp_cipher_alg) {
1458                 case CRYPTO_AES_NIST_GCM_16:
1459                 case CRYPTO_AES_CCM_16:
1460                 case CRYPTO_CHACHA20_POLY1305:
1461                         break;
1462                 default:
1463                         return (EINVAL);
1464                 }
1465                 break;
1466         case CSP_MODE_ETA:
1467                 /* AEAD algorithms cannot be used for EtA. */
1468                 switch (csp->csp_cipher_alg) {
1469                 case CRYPTO_AES_NIST_GCM_16:
1470                 case CRYPTO_AES_CCM_16:
1471                 case CRYPTO_CHACHA20_POLY1305:
1472                         return (EINVAL);
1473                 }
1474                 switch (csp->csp_auth_alg) {
1475                 case CRYPTO_AES_NIST_GMAC:
1476                 case CRYPTO_AES_CCM_CBC_MAC:
1477                         return (EINVAL);
1478                 }
1479
1480                 if (!swcr_cipher_supported(csp) ||
1481                     !swcr_auth_supported(csp))
1482                         return (EINVAL);
1483                 break;
1484         default:
1485                 return (EINVAL);
1486         }
1487
1488         return (CRYPTODEV_PROBE_SOFTWARE);
1489 }
1490
1491 /*
1492  * Generate a new software session.
1493  */
1494 static int
1495 swcr_newsession(device_t dev, crypto_session_t cses,
1496     const struct crypto_session_params *csp)
1497 {
1498         struct swcr_session *ses;
1499         struct swcr_encdec *swe;
1500         struct swcr_auth *swa;
1501         const struct comp_algo *cxf;
1502         int error;
1503
1504         ses = crypto_get_driver_session(cses);
1505         mtx_init(&ses->swcr_lock, "swcr session lock", NULL, MTX_DEF);
1506
1507         error = 0;
1508         swe = &ses->swcr_encdec;
1509         swa = &ses->swcr_auth;
1510         switch (csp->csp_mode) {
1511         case CSP_MODE_COMPRESS:
1512                 switch (csp->csp_cipher_alg) {
1513                 case CRYPTO_DEFLATE_COMP:
1514                         cxf = &comp_algo_deflate;
1515                         break;
1516 #ifdef INVARIANTS
1517                 default:
1518                         panic("bad compression algo");
1519 #endif
1520                 }
1521                 ses->swcr_compdec.sw_cxf = cxf;
1522                 ses->swcr_process = swcr_compdec;
1523                 break;
1524         case CSP_MODE_CIPHER:
1525                 switch (csp->csp_cipher_alg) {
1526                 case CRYPTO_NULL_CBC:
1527                         ses->swcr_process = swcr_null;
1528                         break;
1529 #ifdef INVARIANTS
1530                 case CRYPTO_AES_NIST_GCM_16:
1531                 case CRYPTO_AES_CCM_16:
1532                 case CRYPTO_CHACHA20_POLY1305:
1533                         panic("bad cipher algo");
1534 #endif
1535                 default:
1536                         error = swcr_setup_cipher(ses, csp);
1537                         if (error == 0)
1538                                 ses->swcr_process = swcr_encdec;
1539                 }
1540                 break;
1541         case CSP_MODE_DIGEST:
1542                 error = swcr_setup_auth(ses, csp);
1543                 break;
1544         case CSP_MODE_AEAD:
1545                 switch (csp->csp_cipher_alg) {
1546                 case CRYPTO_AES_NIST_GCM_16:
1547                         error = swcr_setup_gcm(ses, csp);
1548                         if (error == 0)
1549                                 ses->swcr_process = swcr_gcm;
1550                         break;
1551                 case CRYPTO_AES_CCM_16:
1552                         error = swcr_setup_ccm(ses, csp);
1553                         if (error == 0)
1554                                 ses->swcr_process = swcr_ccm;
1555                         break;
1556                 case CRYPTO_CHACHA20_POLY1305:
1557                         error = swcr_setup_chacha20_poly1305(ses, csp);
1558                         if (error == 0)
1559                                 ses->swcr_process = swcr_chacha20_poly1305;
1560                         break;
1561 #ifdef INVARIANTS
1562                 default:
1563                         panic("bad aead algo");
1564 #endif
1565                 }
1566                 break;
1567         case CSP_MODE_ETA:
1568 #ifdef INVARIANTS
1569                 switch (csp->csp_cipher_alg) {
1570                 case CRYPTO_AES_NIST_GCM_16:
1571                 case CRYPTO_AES_CCM_16:
1572                 case CRYPTO_CHACHA20_POLY1305:
1573                         panic("bad eta cipher algo");
1574                 }
1575                 switch (csp->csp_auth_alg) {
1576                 case CRYPTO_AES_NIST_GMAC:
1577                 case CRYPTO_AES_CCM_CBC_MAC:
1578                         panic("bad eta auth algo");
1579                 }
1580 #endif
1581
1582                 error = swcr_setup_auth(ses, csp);
1583                 if (error)
1584                         break;
1585                 if (csp->csp_cipher_alg == CRYPTO_NULL_CBC) {
1586                         /* Effectively degrade to digest mode. */
1587                         ses->swcr_process = swcr_authcompute;
1588                         break;
1589                 }
1590
1591                 error = swcr_setup_cipher(ses, csp);
1592                 if (error == 0)
1593                         ses->swcr_process = swcr_eta;
1594                 break;
1595         default:
1596                 error = EINVAL;
1597         }
1598
1599         if (error)
1600                 swcr_freesession(dev, cses);
1601         return (error);
1602 }
1603
1604 static void
1605 swcr_freesession(device_t dev, crypto_session_t cses)
1606 {
1607         struct swcr_session *ses;
1608
1609         ses = crypto_get_driver_session(cses);
1610
1611         mtx_destroy(&ses->swcr_lock);
1612
1613         zfree(ses->swcr_encdec.sw_kschedule, M_CRYPTO_DATA);
1614         zfree(ses->swcr_auth.sw_ictx, M_CRYPTO_DATA);
1615         zfree(ses->swcr_auth.sw_octx, M_CRYPTO_DATA);
1616 }
1617
1618 /*
1619  * Process a software request.
1620  */
1621 static int
1622 swcr_process(device_t dev, struct cryptop *crp, int hint)
1623 {
1624         struct swcr_session *ses;
1625
1626         ses = crypto_get_driver_session(crp->crp_session);
1627         mtx_lock(&ses->swcr_lock);
1628
1629         crp->crp_etype = ses->swcr_process(ses, crp);
1630
1631         mtx_unlock(&ses->swcr_lock);
1632         crypto_done(crp);
1633         return (0);
1634 }
1635
1636 static void
1637 swcr_identify(driver_t *drv, device_t parent)
1638 {
1639         /* NB: order 10 is so we get attached after h/w devices */
1640         if (device_find_child(parent, "cryptosoft", -1) == NULL &&
1641             BUS_ADD_CHILD(parent, 10, "cryptosoft", 0) == 0)
1642                 panic("cryptosoft: could not attach");
1643 }
1644
1645 static int
1646 swcr_probe(device_t dev)
1647 {
1648         device_set_desc(dev, "software crypto");
1649         device_quiet(dev);
1650         return (BUS_PROBE_NOWILDCARD);
1651 }
1652
1653 static int
1654 swcr_attach(device_t dev)
1655 {
1656
1657         swcr_id = crypto_get_driverid(dev, sizeof(struct swcr_session),
1658                         CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
1659         if (swcr_id < 0) {
1660                 device_printf(dev, "cannot initialize!");
1661                 return (ENXIO);
1662         }
1663
1664         return (0);
1665 }
1666
1667 static int
1668 swcr_detach(device_t dev)
1669 {
1670         crypto_unregister_all(swcr_id);
1671         return 0;
1672 }
1673
1674 static device_method_t swcr_methods[] = {
1675         DEVMETHOD(device_identify,      swcr_identify),
1676         DEVMETHOD(device_probe,         swcr_probe),
1677         DEVMETHOD(device_attach,        swcr_attach),
1678         DEVMETHOD(device_detach,        swcr_detach),
1679
1680         DEVMETHOD(cryptodev_probesession, swcr_probesession),
1681         DEVMETHOD(cryptodev_newsession, swcr_newsession),
1682         DEVMETHOD(cryptodev_freesession,swcr_freesession),
1683         DEVMETHOD(cryptodev_process,    swcr_process),
1684
1685         {0, 0},
1686 };
1687
1688 static driver_t swcr_driver = {
1689         "cryptosoft",
1690         swcr_methods,
1691         0,              /* NB: no softc */
1692 };
1693 static devclass_t swcr_devclass;
1694
1695 /*
1696  * NB: We explicitly reference the crypto module so we
1697  * get the necessary ordering when built as a loadable
1698  * module.  This is required because we bundle the crypto
1699  * module code together with the cryptosoft driver (otherwise
1700  * normal module dependencies would handle things).
1701  */
1702 extern int crypto_modevent(struct module *, int, void *);
1703 /* XXX where to attach */
1704 DRIVER_MODULE(cryptosoft, nexus, swcr_driver, swcr_devclass, crypto_modevent,0);
1705 MODULE_VERSION(cryptosoft, 1);
1706 MODULE_DEPEND(cryptosoft, crypto, 1, 1, 1);