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