1091d81d1SSam Leffler /* $OpenBSD: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $ */ 2091d81d1SSam Leffler 360727d8bSWarner Losh /*- 4091d81d1SSam Leffler * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu) 56810ad6fSSam Leffler * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting 6091d81d1SSam Leffler * 7091d81d1SSam Leffler * This code was written by Angelos D. Keromytis in Athens, Greece, in 8091d81d1SSam Leffler * February 2000. Network Security Technologies Inc. (NSTI) kindly 9091d81d1SSam Leffler * supported the development of this code. 10091d81d1SSam Leffler * 11091d81d1SSam Leffler * Copyright (c) 2000, 2001 Angelos D. Keromytis 121833d604SJohn Baldwin * Copyright (c) 2014-2021 The FreeBSD Foundation 1308fca7a5SJohn-Mark Gurney * All rights reserved. 1408fca7a5SJohn-Mark Gurney * 1508fca7a5SJohn-Mark Gurney * Portions of this software were developed by John-Mark Gurney 1608fca7a5SJohn-Mark Gurney * under sponsorship of the FreeBSD Foundation and 1708fca7a5SJohn-Mark Gurney * Rubicon Communications, LLC (Netgate). 18091d81d1SSam Leffler * 191833d604SJohn Baldwin * Portions of this software were developed by Ararat River 201833d604SJohn Baldwin * Consulting, LLC under sponsorship of the FreeBSD Foundation. 211833d604SJohn Baldwin * 22091d81d1SSam Leffler * Permission to use, copy, and modify this software with or without fee 23091d81d1SSam Leffler * is hereby granted, provided that this entire notice is included in 24091d81d1SSam Leffler * all source code copies of any software which is or includes a copy or 25091d81d1SSam Leffler * modification of this software. 26091d81d1SSam Leffler * 27091d81d1SSam Leffler * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 28091d81d1SSam Leffler * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY 29091d81d1SSam Leffler * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 30091d81d1SSam Leffler * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 31091d81d1SSam Leffler * PURPOSE. 32091d81d1SSam Leffler */ 33091d81d1SSam Leffler 342c446514SDavid E. O'Brien #include <sys/cdefs.h> 352c446514SDavid E. O'Brien __FBSDID("$FreeBSD$"); 362c446514SDavid E. O'Brien 37091d81d1SSam Leffler #include <sys/param.h> 38091d81d1SSam Leffler #include <sys/systm.h> 39091d81d1SSam Leffler #include <sys/malloc.h> 40091d81d1SSam Leffler #include <sys/mbuf.h> 416810ad6fSSam Leffler #include <sys/module.h> 42091d81d1SSam Leffler #include <sys/sysctl.h> 43091d81d1SSam Leffler #include <sys/errno.h> 44091d81d1SSam Leffler #include <sys/random.h> 45091d81d1SSam Leffler #include <sys/kernel.h> 46091d81d1SSam Leffler #include <sys/uio.h> 47109919c6SBenno Rice #include <sys/lock.h> 48109919c6SBenno Rice #include <sys/rwlock.h> 4908fca7a5SJohn-Mark Gurney #include <sys/endian.h> 5008fca7a5SJohn-Mark Gurney #include <sys/limits.h> 51a7fcb1afSSean Eric Fagan #include <sys/mutex.h> 52091d81d1SSam Leffler 53091d81d1SSam Leffler #include <crypto/sha1.h> 54091d81d1SSam Leffler #include <opencrypto/rmd160.h> 55091d81d1SSam Leffler 56091d81d1SSam Leffler #include <opencrypto/cryptodev.h> 57091d81d1SSam Leffler #include <opencrypto/xform.h> 58091d81d1SSam Leffler 596810ad6fSSam Leffler #include <sys/kobj.h> 606810ad6fSSam Leffler #include <sys/bus.h> 616810ad6fSSam Leffler #include "cryptodev_if.h" 62091d81d1SSam Leffler 63c0341432SJohn Baldwin struct swcr_auth { 64c0341432SJohn Baldwin void *sw_ictx; 65c0341432SJohn Baldwin void *sw_octx; 66d8787d4fSMark Johnston const struct auth_hash *sw_axf; 67c0341432SJohn Baldwin uint16_t sw_mlen; 68c0341432SJohn Baldwin }; 69c0341432SJohn Baldwin 70c0341432SJohn Baldwin struct swcr_encdec { 713e947048SJohn Baldwin void *sw_kschedule; 72d8787d4fSMark Johnston const struct enc_xform *sw_exf; 73c0341432SJohn Baldwin }; 74c0341432SJohn Baldwin 75c0341432SJohn Baldwin struct swcr_compdec { 76d8787d4fSMark Johnston const struct comp_algo *sw_cxf; 77c0341432SJohn Baldwin }; 78c0341432SJohn Baldwin 79c0341432SJohn Baldwin struct swcr_session { 80c0341432SJohn Baldwin struct mtx swcr_lock; 81c0341432SJohn Baldwin int (*swcr_process)(struct swcr_session *, struct cryptop *); 82c0341432SJohn Baldwin 83c0341432SJohn Baldwin struct swcr_auth swcr_auth; 84c0341432SJohn Baldwin struct swcr_encdec swcr_encdec; 85c0341432SJohn Baldwin struct swcr_compdec swcr_compdec; 86c0341432SJohn Baldwin }; 87507281e5SSean Eric Fagan 886810ad6fSSam Leffler static int32_t swcr_id; 896810ad6fSSam Leffler 901b0909d5SConrad Meyer static void swcr_freesession(device_t dev, crypto_session_t cses); 91091d81d1SSam Leffler 92c0341432SJohn Baldwin /* Used for CRYPTO_NULL_CBC. */ 93c0341432SJohn Baldwin static int 94c0341432SJohn Baldwin swcr_null(struct swcr_session *ses, struct cryptop *crp) 95c0341432SJohn Baldwin { 96c0341432SJohn Baldwin 97c0341432SJohn Baldwin return (0); 98c0341432SJohn Baldwin } 99c0341432SJohn Baldwin 100091d81d1SSam Leffler /* 101091d81d1SSam Leffler * Apply a symmetric encryption/decryption algorithm. 102091d81d1SSam Leffler */ 103091d81d1SSam Leffler static int 104c0341432SJohn Baldwin swcr_encdec(struct swcr_session *ses, struct cryptop *crp) 105091d81d1SSam Leffler { 1065d7ae54aSConrad Meyer unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN]; 10708fca7a5SJohn-Mark Gurney unsigned char *ivp, *nivp, iv2[EALG_MAX_BLOCK_LEN]; 108c0341432SJohn Baldwin const struct crypto_session_params *csp; 109d8787d4fSMark Johnston const struct enc_xform *exf; 110c0341432SJohn Baldwin struct swcr_encdec *sw; 11186be314dSJohn Baldwin size_t inlen, outlen; 1121833d604SJohn Baldwin int i, blks, resid; 1139c0e3d3aSJohn Baldwin struct crypto_buffer_cursor cc_in, cc_out; 11426d292d3SJohn Baldwin const unsigned char *inblk; 11526d292d3SJohn Baldwin unsigned char *outblk; 11608fca7a5SJohn-Mark Gurney int error; 117c0341432SJohn Baldwin bool encrypting; 11808fca7a5SJohn-Mark Gurney 11908fca7a5SJohn-Mark Gurney error = 0; 120091d81d1SSam Leffler 121c0341432SJohn Baldwin sw = &ses->swcr_encdec; 122091d81d1SSam Leffler exf = sw->sw_exf; 1231833d604SJohn Baldwin csp = crypto_get_params(crp->crp_session); 124091d81d1SSam Leffler 125723d8764SJohn Baldwin if (exf->native_blocksize == 0) { 126091d81d1SSam Leffler /* Check for non-padded data */ 127723d8764SJohn Baldwin if ((crp->crp_payload_length % exf->blocksize) != 0) 128723d8764SJohn Baldwin return (EINVAL); 129723d8764SJohn Baldwin 130723d8764SJohn Baldwin blks = exf->blocksize; 131723d8764SJohn Baldwin } else 132723d8764SJohn Baldwin blks = exf->native_blocksize; 133091d81d1SSam Leffler 134c0341432SJohn Baldwin if (exf == &enc_xform_aes_icm && 135c0341432SJohn Baldwin (crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0) 13608fca7a5SJohn-Mark Gurney return (EINVAL); 13708fca7a5SJohn-Mark Gurney 138c0341432SJohn Baldwin if (crp->crp_cipher_key != NULL) { 1393e947048SJohn Baldwin error = exf->setkey(sw->sw_kschedule, 140c0341432SJohn Baldwin crp->crp_cipher_key, csp->csp_cipher_klen); 141c740ae4bSPoul-Henning Kamp if (error) 142c740ae4bSPoul-Henning Kamp return (error); 143c740ae4bSPoul-Henning Kamp } 144d295bdeeSPawel Jakub Dawidek 14520c128daSJohn Baldwin crypto_read_iv(crp, iv); 14620c128daSJohn Baldwin 14708fca7a5SJohn-Mark Gurney if (exf->reinit) { 148d295bdeeSPawel Jakub Dawidek /* 149d295bdeeSPawel Jakub Dawidek * xforms that provide a reinit method perform all IV 150d295bdeeSPawel Jakub Dawidek * handling themselves. 151d295bdeeSPawel Jakub Dawidek */ 1521833d604SJohn Baldwin exf->reinit(sw->sw_kschedule, iv, csp->csp_ivlen); 153091d81d1SSam Leffler } 154091d81d1SSam Leffler 1559c0e3d3aSJohn Baldwin ivp = iv; 156091d81d1SSam Leffler 1579c0e3d3aSJohn Baldwin crypto_cursor_init(&cc_in, &crp->crp_buf); 1589c0e3d3aSJohn Baldwin crypto_cursor_advance(&cc_in, crp->crp_payload_start); 15986be314dSJohn Baldwin inblk = crypto_cursor_segment(&cc_in, &inlen); 1609c0e3d3aSJohn Baldwin if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) { 1619c0e3d3aSJohn Baldwin crypto_cursor_init(&cc_out, &crp->crp_obuf); 1629c0e3d3aSJohn Baldwin crypto_cursor_advance(&cc_out, crp->crp_payload_output_start); 1639c0e3d3aSJohn Baldwin } else 1649c0e3d3aSJohn Baldwin cc_out = cc_in; 16586be314dSJohn Baldwin outblk = crypto_cursor_segment(&cc_out, &outlen); 1669c0e3d3aSJohn Baldwin 1679c0e3d3aSJohn Baldwin resid = crp->crp_payload_length; 168c0341432SJohn Baldwin encrypting = CRYPTO_OP_IS_ENCRYPT(crp->crp_op); 169091d81d1SSam Leffler 170091d81d1SSam Leffler /* 1719c0e3d3aSJohn Baldwin * Loop through encrypting blocks. 'inlen' is the remaining 1729c0e3d3aSJohn Baldwin * length of the current segment in the input buffer. 1739c0e3d3aSJohn Baldwin * 'outlen' is the remaining length of current segment in the 1749c0e3d3aSJohn Baldwin * output buffer. 175091d81d1SSam Leffler */ 1769c0e3d3aSJohn Baldwin while (resid >= blks) { 1779c0e3d3aSJohn Baldwin /* 1789c0e3d3aSJohn Baldwin * If the current block is not contained within the 1799c0e3d3aSJohn Baldwin * current input/output segment, use 'blk' as a local 1809c0e3d3aSJohn Baldwin * buffer. 1819c0e3d3aSJohn Baldwin */ 1829c0e3d3aSJohn Baldwin if (inlen < blks) { 1839c0e3d3aSJohn Baldwin crypto_cursor_copydata(&cc_in, blks, blk); 1849c0e3d3aSJohn Baldwin inblk = blk; 185d295bdeeSPawel Jakub Dawidek } 1869c0e3d3aSJohn Baldwin if (outlen < blks) 1879c0e3d3aSJohn Baldwin outblk = blk; 1889c0e3d3aSJohn Baldwin 1899c0e3d3aSJohn Baldwin /* 1909c0e3d3aSJohn Baldwin * Ciphers without a 'reinit' hook are assumed to be 1919c0e3d3aSJohn Baldwin * used in CBC mode where the chaining is done here. 1929c0e3d3aSJohn Baldwin */ 1939c0e3d3aSJohn Baldwin if (exf->reinit != NULL) { 1949c0e3d3aSJohn Baldwin if (encrypting) 1959c0e3d3aSJohn Baldwin exf->encrypt(sw->sw_kschedule, inblk, outblk); 1969c0e3d3aSJohn Baldwin else 1979c0e3d3aSJohn Baldwin exf->decrypt(sw->sw_kschedule, inblk, outblk); 198c0341432SJohn Baldwin } else if (encrypting) { 199091d81d1SSam Leffler /* XOR with previous block */ 2009c0e3d3aSJohn Baldwin for (i = 0; i < blks; i++) 2019c0e3d3aSJohn Baldwin outblk[i] = inblk[i] ^ ivp[i]; 202091d81d1SSam Leffler 2039c0e3d3aSJohn Baldwin exf->encrypt(sw->sw_kschedule, outblk, outblk); 204091d81d1SSam Leffler 205091d81d1SSam Leffler /* 206091d81d1SSam Leffler * Keep encrypted block for XOR'ing 207091d81d1SSam Leffler * with next block 208091d81d1SSam Leffler */ 2099c0e3d3aSJohn Baldwin memcpy(iv, outblk, blks); 210091d81d1SSam Leffler ivp = iv; 211091d81d1SSam Leffler } else { /* decrypt */ 212091d81d1SSam Leffler /* 213091d81d1SSam Leffler * Keep encrypted block for XOR'ing 214091d81d1SSam Leffler * with next block 215091d81d1SSam Leffler */ 21608fca7a5SJohn-Mark Gurney nivp = (ivp == iv) ? iv2 : iv; 2179c0e3d3aSJohn Baldwin memcpy(nivp, inblk, blks); 218091d81d1SSam Leffler 2199c0e3d3aSJohn Baldwin exf->decrypt(sw->sw_kschedule, inblk, outblk); 220091d81d1SSam Leffler 221091d81d1SSam Leffler /* XOR with previous block */ 2229c0e3d3aSJohn Baldwin for (i = 0; i < blks; i++) 2239c0e3d3aSJohn Baldwin outblk[i] ^= ivp[i]; 224091d81d1SSam Leffler 22508fca7a5SJohn-Mark Gurney ivp = nivp; 226091d81d1SSam Leffler } 227091d81d1SSam Leffler 2289c0e3d3aSJohn Baldwin if (inlen < blks) { 22986be314dSJohn Baldwin inblk = crypto_cursor_segment(&cc_in, &inlen); 2309c0e3d3aSJohn Baldwin } else { 2319c0e3d3aSJohn Baldwin crypto_cursor_advance(&cc_in, blks); 2329c0e3d3aSJohn Baldwin inlen -= blks; 2339c0e3d3aSJohn Baldwin inblk += blks; 23408fca7a5SJohn-Mark Gurney } 235091d81d1SSam Leffler 2369c0e3d3aSJohn Baldwin if (outlen < blks) { 2379c0e3d3aSJohn Baldwin crypto_cursor_copyback(&cc_out, blks, blk); 23886be314dSJohn Baldwin outblk = crypto_cursor_segment(&cc_out, &outlen); 2399c0e3d3aSJohn Baldwin } else { 2409c0e3d3aSJohn Baldwin crypto_cursor_advance(&cc_out, blks); 2419c0e3d3aSJohn Baldwin outlen -= blks; 2429c0e3d3aSJohn Baldwin outblk += blks; 243091d81d1SSam Leffler } 244091d81d1SSam Leffler 2459c0e3d3aSJohn Baldwin resid -= blks; 246f34a967bSPawel Jakub Dawidek } 247f34a967bSPawel Jakub Dawidek 248723d8764SJohn Baldwin /* Handle trailing partial block for stream ciphers. */ 2499c0e3d3aSJohn Baldwin if (resid > 0) { 250723d8764SJohn Baldwin KASSERT(exf->native_blocksize != 0, 251723d8764SJohn Baldwin ("%s: partial block of %d bytes for cipher %s", 252723d8764SJohn Baldwin __func__, i, exf->name)); 253723d8764SJohn Baldwin KASSERT(exf->reinit != NULL, 254723d8764SJohn Baldwin ("%s: partial block cipher %s without reinit hook", 255723d8764SJohn Baldwin __func__, exf->name)); 2569c0e3d3aSJohn Baldwin KASSERT(resid < blks, ("%s: partial block too big", __func__)); 257723d8764SJohn Baldwin 25886be314dSJohn Baldwin inblk = crypto_cursor_segment(&cc_in, &inlen); 25986be314dSJohn Baldwin outblk = crypto_cursor_segment(&cc_out, &outlen); 2609c0e3d3aSJohn Baldwin if (inlen < resid) { 2619c0e3d3aSJohn Baldwin crypto_cursor_copydata(&cc_in, resid, blk); 2629c0e3d3aSJohn Baldwin inblk = blk; 26386be314dSJohn Baldwin } 2649c0e3d3aSJohn Baldwin if (outlen < resid) 2659c0e3d3aSJohn Baldwin outblk = blk; 2669c0e3d3aSJohn Baldwin if (encrypting) 2679c0e3d3aSJohn Baldwin exf->encrypt_last(sw->sw_kschedule, inblk, outblk, 2689c0e3d3aSJohn Baldwin resid); 2699c0e3d3aSJohn Baldwin else 2709c0e3d3aSJohn Baldwin exf->decrypt_last(sw->sw_kschedule, inblk, outblk, 2719c0e3d3aSJohn Baldwin resid); 2729c0e3d3aSJohn Baldwin if (outlen < resid) 2739c0e3d3aSJohn Baldwin crypto_cursor_copyback(&cc_out, resid, blk); 274723d8764SJohn Baldwin } 275723d8764SJohn Baldwin 27620c128daSJohn Baldwin explicit_bzero(blk, sizeof(blk)); 27720c128daSJohn Baldwin explicit_bzero(iv, sizeof(iv)); 27820c128daSJohn Baldwin explicit_bzero(iv2, sizeof(iv2)); 2799c0e3d3aSJohn Baldwin return (0); 280091d81d1SSam Leffler } 281091d81d1SSam Leffler 282c0341432SJohn Baldwin static void 283d8787d4fSMark Johnston swcr_authprepare(const struct auth_hash *axf, struct swcr_auth *sw, 284c0341432SJohn Baldwin const uint8_t *key, int klen) 285f6c4bc3bSPawel Jakub Dawidek { 286f6c4bc3bSPawel Jakub Dawidek 287f6c4bc3bSPawel Jakub Dawidek switch (axf->type) { 288f6c4bc3bSPawel Jakub Dawidek case CRYPTO_SHA1_HMAC: 289c97f39ceSConrad Meyer case CRYPTO_SHA2_224_HMAC: 290f6c4bc3bSPawel Jakub Dawidek case CRYPTO_SHA2_256_HMAC: 291f6c4bc3bSPawel Jakub Dawidek case CRYPTO_SHA2_384_HMAC: 292f6c4bc3bSPawel Jakub Dawidek case CRYPTO_SHA2_512_HMAC: 293f6c4bc3bSPawel Jakub Dawidek case CRYPTO_NULL_HMAC: 294f6c4bc3bSPawel Jakub Dawidek case CRYPTO_RIPEMD160_HMAC: 295c0341432SJohn Baldwin hmac_init_ipad(axf, key, klen, sw->sw_ictx); 296c0341432SJohn Baldwin hmac_init_opad(axf, key, klen, sw->sw_octx); 297f6c4bc3bSPawel Jakub Dawidek break; 29825b7033bSConrad Meyer case CRYPTO_POLY1305: 2990e33efe4SConrad Meyer case CRYPTO_BLAKE2B: 3000e33efe4SConrad Meyer case CRYPTO_BLAKE2S: 3010e33efe4SConrad Meyer axf->Setkey(sw->sw_ictx, key, klen); 3020e33efe4SConrad Meyer axf->Init(sw->sw_ictx); 3030e33efe4SConrad Meyer break; 304f6c4bc3bSPawel Jakub Dawidek default: 305c0341432SJohn Baldwin panic("%s: algorithm %d doesn't use keys", __func__, axf->type); 306f6c4bc3bSPawel Jakub Dawidek } 307f6c4bc3bSPawel Jakub Dawidek } 308f6c4bc3bSPawel Jakub Dawidek 309091d81d1SSam Leffler /* 310c0341432SJohn Baldwin * Compute or verify hash. 311091d81d1SSam Leffler */ 312091d81d1SSam Leffler static int 313c0341432SJohn Baldwin swcr_authcompute(struct swcr_session *ses, struct cryptop *crp) 314091d81d1SSam Leffler { 315c0341432SJohn Baldwin u_char aalg[HASH_MAX_LEN]; 316c0341432SJohn Baldwin const struct crypto_session_params *csp; 317c0341432SJohn Baldwin struct swcr_auth *sw; 318d8787d4fSMark Johnston const struct auth_hash *axf; 319091d81d1SSam Leffler union authctx ctx; 320091d81d1SSam Leffler int err; 321091d81d1SSam Leffler 322c0341432SJohn Baldwin sw = &ses->swcr_auth; 323091d81d1SSam Leffler 324091d81d1SSam Leffler axf = sw->sw_axf; 325091d81d1SSam Leffler 326c0341432SJohn Baldwin csp = crypto_get_params(crp->crp_session); 3276038018aSMarcin Wojtas if (crp->crp_auth_key != NULL) { 328c0341432SJohn Baldwin swcr_authprepare(axf, sw, crp->crp_auth_key, 329c0341432SJohn Baldwin csp->csp_auth_klen); 33025b7033bSConrad Meyer } 331f6c4bc3bSPawel Jakub Dawidek 332091d81d1SSam Leffler bcopy(sw->sw_ictx, &ctx, axf->ctxsize); 333091d81d1SSam Leffler 3349b774dc0SJohn Baldwin if (crp->crp_aad != NULL) 3359b774dc0SJohn Baldwin err = axf->Update(&ctx, crp->crp_aad, crp->crp_aad_length); 3369b774dc0SJohn Baldwin else 337c0341432SJohn Baldwin err = crypto_apply(crp, crp->crp_aad_start, crp->crp_aad_length, 3389b6b2f86SJohn Baldwin axf->Update, &ctx); 339091d81d1SSam Leffler if (err) 340e0b155feSJohn Baldwin goto out; 341091d81d1SSam Leffler 3429c0e3d3aSJohn Baldwin if (CRYPTO_HAS_OUTPUT_BUFFER(crp) && 3439c0e3d3aSJohn Baldwin CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) 3449c0e3d3aSJohn Baldwin err = crypto_apply_buf(&crp->crp_obuf, 3459c0e3d3aSJohn Baldwin crp->crp_payload_output_start, crp->crp_payload_length, 3469b6b2f86SJohn Baldwin axf->Update, &ctx); 3479c0e3d3aSJohn Baldwin else 3489c0e3d3aSJohn Baldwin err = crypto_apply(crp, crp->crp_payload_start, 3499b6b2f86SJohn Baldwin crp->crp_payload_length, axf->Update, &ctx); 350c0341432SJohn Baldwin if (err) 351e0b155feSJohn Baldwin goto out; 352091d81d1SSam Leffler 3536038018aSMarcin Wojtas if (csp->csp_flags & CSP_F_ESN) 3546038018aSMarcin Wojtas axf->Update(&ctx, crp->crp_esn, 4); 3556038018aSMarcin Wojtas 356091d81d1SSam Leffler axf->Final(aalg, &ctx); 357e0b155feSJohn Baldwin if (sw->sw_octx != NULL) { 358091d81d1SSam Leffler bcopy(sw->sw_octx, &ctx, axf->ctxsize); 359091d81d1SSam Leffler axf->Update(&ctx, aalg, axf->hashsize); 360091d81d1SSam Leffler axf->Final(aalg, &ctx); 361091d81d1SSam Leffler } 362091d81d1SSam Leffler 363c0341432SJohn Baldwin if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) { 36420c128daSJohn Baldwin u_char uaalg[HASH_MAX_LEN]; 36520c128daSJohn Baldwin 366c0341432SJohn Baldwin crypto_copydata(crp, crp->crp_digest_start, sw->sw_mlen, uaalg); 367c0341432SJohn Baldwin if (timingsafe_bcmp(aalg, uaalg, sw->sw_mlen) != 0) 36820c128daSJohn Baldwin err = EBADMSG; 36920c128daSJohn Baldwin explicit_bzero(uaalg, sizeof(uaalg)); 370c0341432SJohn Baldwin } else { 371091d81d1SSam Leffler /* Inject the authentication data */ 372c0341432SJohn Baldwin crypto_copyback(crp, crp->crp_digest_start, sw->sw_mlen, aalg); 373c0341432SJohn Baldwin } 37420c128daSJohn Baldwin explicit_bzero(aalg, sizeof(aalg)); 375e0b155feSJohn Baldwin out: 376e0b155feSJohn Baldwin explicit_bzero(&ctx, sizeof(ctx)); 37720c128daSJohn Baldwin return (err); 378091d81d1SSam Leffler } 379091d81d1SSam Leffler 38008fca7a5SJohn-Mark Gurney CTASSERT(INT_MAX <= (1ll<<39) - 256); /* GCM: plain text < 2^39-256 */ 38108fca7a5SJohn-Mark Gurney CTASSERT(INT_MAX <= (uint64_t)-1); /* GCM: associated data <= 2^64-1 */ 38208fca7a5SJohn-Mark Gurney 38308fca7a5SJohn-Mark Gurney static int 384c0341432SJohn Baldwin swcr_gmac(struct swcr_session *ses, struct cryptop *crp) 38508fca7a5SJohn-Mark Gurney { 38626d292d3SJohn Baldwin uint32_t blkbuf[howmany(AES_BLOCK_LEN, sizeof(uint32_t))]; 38708fca7a5SJohn-Mark Gurney u_char *blk = (u_char *)blkbuf; 38826d292d3SJohn Baldwin u_char tag[GMAC_DIGEST_LEN]; 38926d292d3SJohn Baldwin u_char iv[AES_BLOCK_LEN]; 3909c0e3d3aSJohn Baldwin struct crypto_buffer_cursor cc; 39126d292d3SJohn Baldwin const u_char *inblk; 39208fca7a5SJohn-Mark Gurney union authctx ctx; 393c0341432SJohn Baldwin struct swcr_auth *swa; 394d8787d4fSMark Johnston const struct auth_hash *axf; 39508fca7a5SJohn-Mark Gurney uint32_t *blkp; 39686be314dSJohn Baldwin size_t len; 39786be314dSJohn Baldwin int blksz, error, ivlen, resid; 39808fca7a5SJohn-Mark Gurney 399c0341432SJohn Baldwin swa = &ses->swcr_auth; 40008fca7a5SJohn-Mark Gurney axf = swa->sw_axf; 401c0341432SJohn Baldwin 40208fca7a5SJohn-Mark Gurney bcopy(swa->sw_ictx, &ctx, axf->ctxsize); 40326d292d3SJohn Baldwin blksz = GMAC_BLOCK_LEN; 40426d292d3SJohn Baldwin KASSERT(axf->blocksize == blksz, ("%s: axf block size mismatch", 40526d292d3SJohn Baldwin __func__)); 40608fca7a5SJohn-Mark Gurney 40708fca7a5SJohn-Mark Gurney /* Initialize the IV */ 408c0341432SJohn Baldwin ivlen = AES_GCM_IV_LEN; 40929fe41ddSJohn Baldwin crypto_read_iv(crp, iv); 41008fca7a5SJohn-Mark Gurney 41108fca7a5SJohn-Mark Gurney axf->Reinit(&ctx, iv, ivlen); 4129c0e3d3aSJohn Baldwin crypto_cursor_init(&cc, &crp->crp_buf); 4139c0e3d3aSJohn Baldwin crypto_cursor_advance(&cc, crp->crp_payload_start); 41426d292d3SJohn Baldwin for (resid = crp->crp_payload_length; resid >= blksz; resid -= len) { 41586be314dSJohn Baldwin inblk = crypto_cursor_segment(&cc, &len); 41626d292d3SJohn Baldwin if (len >= blksz) { 41726d292d3SJohn Baldwin len = rounddown(MIN(len, resid), blksz); 41826d292d3SJohn Baldwin crypto_cursor_advance(&cc, len); 41926d292d3SJohn Baldwin } else { 42026d292d3SJohn Baldwin len = blksz; 4219c0e3d3aSJohn Baldwin crypto_cursor_copydata(&cc, len, blk); 42226d292d3SJohn Baldwin inblk = blk; 42326d292d3SJohn Baldwin } 42426d292d3SJohn Baldwin axf->Update(&ctx, inblk, len); 42526d292d3SJohn Baldwin } 42626d292d3SJohn Baldwin if (resid > 0) { 42726d292d3SJohn Baldwin memset(blk, 0, blksz); 42826d292d3SJohn Baldwin crypto_cursor_copydata(&cc, resid, blk); 42908fca7a5SJohn-Mark Gurney axf->Update(&ctx, blk, blksz); 43008fca7a5SJohn-Mark Gurney } 43108fca7a5SJohn-Mark Gurney 43208fca7a5SJohn-Mark Gurney /* length block */ 43326d292d3SJohn Baldwin memset(blk, 0, blksz); 43408fca7a5SJohn-Mark Gurney blkp = (uint32_t *)blk + 1; 435c0341432SJohn Baldwin *blkp = htobe32(crp->crp_payload_length * 8); 43608fca7a5SJohn-Mark Gurney axf->Update(&ctx, blk, blksz); 437c0341432SJohn Baldwin 438c0341432SJohn Baldwin /* Finalize MAC */ 43926d292d3SJohn Baldwin axf->Final(tag, &ctx); 440c0341432SJohn Baldwin 44120c128daSJohn Baldwin error = 0; 442c0341432SJohn Baldwin if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) { 44326d292d3SJohn Baldwin u_char tag2[GMAC_DIGEST_LEN]; 44420c128daSJohn Baldwin 445c0341432SJohn Baldwin crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen, 44626d292d3SJohn Baldwin tag2); 44726d292d3SJohn Baldwin if (timingsafe_bcmp(tag, tag2, swa->sw_mlen) != 0) 44820c128daSJohn Baldwin error = EBADMSG; 44926d292d3SJohn Baldwin explicit_bzero(tag2, sizeof(tag2)); 450c0341432SJohn Baldwin } else { 451c0341432SJohn Baldwin /* Inject the authentication data */ 45226d292d3SJohn Baldwin crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag); 453c0341432SJohn Baldwin } 45420c128daSJohn Baldwin explicit_bzero(blkbuf, sizeof(blkbuf)); 45526d292d3SJohn Baldwin explicit_bzero(tag, sizeof(tag)); 45620c128daSJohn Baldwin explicit_bzero(iv, sizeof(iv)); 45720c128daSJohn Baldwin return (error); 458c0341432SJohn Baldwin } 459c0341432SJohn Baldwin 460c0341432SJohn Baldwin static int 461c0341432SJohn Baldwin swcr_gcm(struct swcr_session *ses, struct cryptop *crp) 462c0341432SJohn Baldwin { 46326d292d3SJohn Baldwin uint32_t blkbuf[howmany(AES_BLOCK_LEN, sizeof(uint32_t))]; 464c0341432SJohn Baldwin u_char *blk = (u_char *)blkbuf; 46526d292d3SJohn Baldwin u_char tag[GMAC_DIGEST_LEN]; 4669c0e3d3aSJohn Baldwin struct crypto_buffer_cursor cc_in, cc_out; 46726d292d3SJohn Baldwin const u_char *inblk; 46826d292d3SJohn Baldwin u_char *outblk; 469c0341432SJohn Baldwin union authctx ctx; 470c0341432SJohn Baldwin struct swcr_auth *swa; 471c0341432SJohn Baldwin struct swcr_encdec *swe; 472d8787d4fSMark Johnston const struct auth_hash *axf; 473d8787d4fSMark Johnston const struct enc_xform *exf; 474c0341432SJohn Baldwin uint32_t *blkp; 47586be314dSJohn Baldwin size_t len; 47686be314dSJohn Baldwin int blksz, error, ivlen, r, resid; 477c0341432SJohn Baldwin 478c0341432SJohn Baldwin swa = &ses->swcr_auth; 479c0341432SJohn Baldwin axf = swa->sw_axf; 480c0341432SJohn Baldwin 481c0341432SJohn Baldwin bcopy(swa->sw_ictx, &ctx, axf->ctxsize); 48226d292d3SJohn Baldwin blksz = GMAC_BLOCK_LEN; 48326d292d3SJohn Baldwin KASSERT(axf->blocksize == blksz, ("%s: axf block size mismatch", 48426d292d3SJohn Baldwin __func__)); 485c0341432SJohn Baldwin 486c0341432SJohn Baldwin swe = &ses->swcr_encdec; 487c0341432SJohn Baldwin exf = swe->sw_exf; 488723d8764SJohn Baldwin KASSERT(axf->blocksize == exf->native_blocksize, 489723d8764SJohn Baldwin ("%s: blocksize mismatch", __func__)); 490c0341432SJohn Baldwin 491c0341432SJohn Baldwin if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0) 492c0341432SJohn Baldwin return (EINVAL); 493c0341432SJohn Baldwin 494c0341432SJohn Baldwin ivlen = AES_GCM_IV_LEN; 495c0341432SJohn Baldwin 496c0341432SJohn Baldwin /* Supply MAC with IV */ 4975ae5ed5bSJohn Baldwin axf->Reinit(&ctx, crp->crp_iv, ivlen); 498c0341432SJohn Baldwin 499c0341432SJohn Baldwin /* Supply MAC with AAD */ 5009b774dc0SJohn Baldwin if (crp->crp_aad != NULL) { 5019b774dc0SJohn Baldwin len = rounddown(crp->crp_aad_length, blksz); 5029b774dc0SJohn Baldwin if (len != 0) 5039b774dc0SJohn Baldwin axf->Update(&ctx, crp->crp_aad, len); 5049b774dc0SJohn Baldwin if (crp->crp_aad_length != len) { 5059b774dc0SJohn Baldwin memset(blk, 0, blksz); 5069b774dc0SJohn Baldwin memcpy(blk, (char *)crp->crp_aad + len, 5079b774dc0SJohn Baldwin crp->crp_aad_length - len); 5089b774dc0SJohn Baldwin axf->Update(&ctx, blk, blksz); 5099b774dc0SJohn Baldwin } 5109b774dc0SJohn Baldwin } else { 5119c0e3d3aSJohn Baldwin crypto_cursor_init(&cc_in, &crp->crp_buf); 5129c0e3d3aSJohn Baldwin crypto_cursor_advance(&cc_in, crp->crp_aad_start); 5139b774dc0SJohn Baldwin for (resid = crp->crp_aad_length; resid >= blksz; 5149b774dc0SJohn Baldwin resid -= len) { 51586be314dSJohn Baldwin inblk = crypto_cursor_segment(&cc_in, &len); 51626d292d3SJohn Baldwin if (len >= blksz) { 51726d292d3SJohn Baldwin len = rounddown(MIN(len, resid), blksz); 51826d292d3SJohn Baldwin crypto_cursor_advance(&cc_in, len); 51926d292d3SJohn Baldwin } else { 52026d292d3SJohn Baldwin len = blksz; 5219c0e3d3aSJohn Baldwin crypto_cursor_copydata(&cc_in, len, blk); 52226d292d3SJohn Baldwin inblk = blk; 52326d292d3SJohn Baldwin } 52426d292d3SJohn Baldwin axf->Update(&ctx, inblk, len); 52526d292d3SJohn Baldwin } 52626d292d3SJohn Baldwin if (resid > 0) { 52726d292d3SJohn Baldwin memset(blk, 0, blksz); 52826d292d3SJohn Baldwin crypto_cursor_copydata(&cc_in, resid, blk); 529c0341432SJohn Baldwin axf->Update(&ctx, blk, blksz); 530c0341432SJohn Baldwin } 5319b774dc0SJohn Baldwin } 532c0341432SJohn Baldwin 533a10020cfSJohn Baldwin if (crp->crp_cipher_key != NULL) 534a10020cfSJohn Baldwin exf->setkey(swe->sw_kschedule, crp->crp_cipher_key, 535a10020cfSJohn Baldwin crypto_get_params(crp->crp_session)->csp_cipher_klen); 5365ae5ed5bSJohn Baldwin exf->reinit(swe->sw_kschedule, crp->crp_iv, ivlen); 537c0341432SJohn Baldwin 538c0341432SJohn Baldwin /* Do encryption with MAC */ 5399c0e3d3aSJohn Baldwin crypto_cursor_init(&cc_in, &crp->crp_buf); 5409c0e3d3aSJohn Baldwin crypto_cursor_advance(&cc_in, crp->crp_payload_start); 5419c0e3d3aSJohn Baldwin if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) { 5429c0e3d3aSJohn Baldwin crypto_cursor_init(&cc_out, &crp->crp_obuf); 5439c0e3d3aSJohn Baldwin crypto_cursor_advance(&cc_out, crp->crp_payload_output_start); 5449c0e3d3aSJohn Baldwin } else 5459c0e3d3aSJohn Baldwin cc_out = cc_in; 54626d292d3SJohn Baldwin for (resid = crp->crp_payload_length; resid >= blksz; resid -= blksz) { 54786be314dSJohn Baldwin inblk = crypto_cursor_segment(&cc_in, &len); 54886be314dSJohn Baldwin if (len < blksz) { 54926d292d3SJohn Baldwin crypto_cursor_copydata(&cc_in, blksz, blk); 55026d292d3SJohn Baldwin inblk = blk; 551c0341432SJohn Baldwin } else { 55226d292d3SJohn Baldwin crypto_cursor_advance(&cc_in, blksz); 553c0341432SJohn Baldwin } 55426d292d3SJohn Baldwin if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { 55586be314dSJohn Baldwin outblk = crypto_cursor_segment(&cc_out, &len); 55686be314dSJohn Baldwin if (len < blksz) 55726d292d3SJohn Baldwin outblk = blk; 55826d292d3SJohn Baldwin exf->encrypt(swe->sw_kschedule, inblk, outblk); 55926d292d3SJohn Baldwin axf->Update(&ctx, outblk, blksz); 56026d292d3SJohn Baldwin if (outblk == blk) 56126d292d3SJohn Baldwin crypto_cursor_copyback(&cc_out, blksz, blk); 56226d292d3SJohn Baldwin else 56326d292d3SJohn Baldwin crypto_cursor_advance(&cc_out, blksz); 56426d292d3SJohn Baldwin } else { 56526d292d3SJohn Baldwin axf->Update(&ctx, inblk, blksz); 56626d292d3SJohn Baldwin } 56726d292d3SJohn Baldwin } 56826d292d3SJohn Baldwin if (resid > 0) { 56926d292d3SJohn Baldwin crypto_cursor_copydata(&cc_in, resid, blk); 57026d292d3SJohn Baldwin if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { 57126d292d3SJohn Baldwin exf->encrypt_last(swe->sw_kschedule, blk, blk, resid); 57226d292d3SJohn Baldwin crypto_cursor_copyback(&cc_out, resid, blk); 57326d292d3SJohn Baldwin } 57426d292d3SJohn Baldwin axf->Update(&ctx, blk, resid); 575c0341432SJohn Baldwin } 576c0341432SJohn Baldwin 577c0341432SJohn Baldwin /* length block */ 57826d292d3SJohn Baldwin memset(blk, 0, blksz); 579c0341432SJohn Baldwin blkp = (uint32_t *)blk + 1; 580c0341432SJohn Baldwin *blkp = htobe32(crp->crp_aad_length * 8); 581c0341432SJohn Baldwin blkp = (uint32_t *)blk + 3; 582c0341432SJohn Baldwin *blkp = htobe32(crp->crp_payload_length * 8); 583c0341432SJohn Baldwin axf->Update(&ctx, blk, blksz); 584c0341432SJohn Baldwin 585c0341432SJohn Baldwin /* Finalize MAC */ 58626d292d3SJohn Baldwin axf->Final(tag, &ctx); 587c0341432SJohn Baldwin 588c0341432SJohn Baldwin /* Validate tag */ 58920c128daSJohn Baldwin error = 0; 590c0341432SJohn Baldwin if (!CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { 59126d292d3SJohn Baldwin u_char tag2[GMAC_DIGEST_LEN]; 59220c128daSJohn Baldwin 59326d292d3SJohn Baldwin crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen, tag2); 594c0341432SJohn Baldwin 59526d292d3SJohn Baldwin r = timingsafe_bcmp(tag, tag2, swa->sw_mlen); 59626d292d3SJohn Baldwin explicit_bzero(tag2, sizeof(tag2)); 59720c128daSJohn Baldwin if (r != 0) { 59820c128daSJohn Baldwin error = EBADMSG; 59920c128daSJohn Baldwin goto out; 60020c128daSJohn Baldwin } 601c0341432SJohn Baldwin 602c0341432SJohn Baldwin /* tag matches, decrypt data */ 6039c0e3d3aSJohn Baldwin crypto_cursor_init(&cc_in, &crp->crp_buf); 6049c0e3d3aSJohn Baldwin crypto_cursor_advance(&cc_in, crp->crp_payload_start); 60526d292d3SJohn Baldwin for (resid = crp->crp_payload_length; resid > blksz; 60626d292d3SJohn Baldwin resid -= blksz) { 60786be314dSJohn Baldwin inblk = crypto_cursor_segment(&cc_in, &len); 60886be314dSJohn Baldwin if (len < blksz) { 60926d292d3SJohn Baldwin crypto_cursor_copydata(&cc_in, blksz, blk); 61026d292d3SJohn Baldwin inblk = blk; 61186be314dSJohn Baldwin } else 61226d292d3SJohn Baldwin crypto_cursor_advance(&cc_in, blksz); 61386be314dSJohn Baldwin outblk = crypto_cursor_segment(&cc_out, &len); 61486be314dSJohn Baldwin if (len < blksz) 61526d292d3SJohn Baldwin outblk = blk; 61626d292d3SJohn Baldwin exf->decrypt(swe->sw_kschedule, inblk, outblk); 61726d292d3SJohn Baldwin if (outblk == blk) 61826d292d3SJohn Baldwin crypto_cursor_copyback(&cc_out, blksz, blk); 61926d292d3SJohn Baldwin else 62026d292d3SJohn Baldwin crypto_cursor_advance(&cc_out, blksz); 62126d292d3SJohn Baldwin } 62226d292d3SJohn Baldwin if (resid > 0) { 62326d292d3SJohn Baldwin crypto_cursor_copydata(&cc_in, resid, blk); 62426d292d3SJohn Baldwin exf->decrypt_last(swe->sw_kschedule, blk, blk, resid); 62526d292d3SJohn Baldwin crypto_cursor_copyback(&cc_out, resid, blk); 626c0341432SJohn Baldwin } 627c0341432SJohn Baldwin } else { 628c0341432SJohn Baldwin /* Inject the authentication data */ 62926d292d3SJohn Baldwin crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag); 630c0341432SJohn Baldwin } 631c0341432SJohn Baldwin 63220c128daSJohn Baldwin out: 63320c128daSJohn Baldwin explicit_bzero(blkbuf, sizeof(blkbuf)); 63426d292d3SJohn Baldwin explicit_bzero(tag, sizeof(tag)); 63520c128daSJohn Baldwin 63620c128daSJohn Baldwin return (error); 637c0341432SJohn Baldwin } 638c0341432SJohn Baldwin 639*4361c4ebSJohn Baldwin static void 640*4361c4ebSJohn Baldwin build_ccm_b0(const char *nonce, u_int nonce_length, u_int aad_length, 641*4361c4ebSJohn Baldwin u_int data_length, u_int tag_length, uint8_t *b0) 642*4361c4ebSJohn Baldwin { 643*4361c4ebSJohn Baldwin uint8_t *bp; 644*4361c4ebSJohn Baldwin uint8_t flags, L; 645*4361c4ebSJohn Baldwin 646*4361c4ebSJohn Baldwin KASSERT(nonce_length >= 7 && nonce_length <= 13, 647*4361c4ebSJohn Baldwin ("nonce_length must be between 7 and 13 bytes")); 648*4361c4ebSJohn Baldwin 649*4361c4ebSJohn Baldwin /* 650*4361c4ebSJohn Baldwin * Need to determine the L field value. This is the number of 651*4361c4ebSJohn Baldwin * bytes needed to specify the length of the message; the length 652*4361c4ebSJohn Baldwin * is whatever is left in the 16 bytes after specifying flags and 653*4361c4ebSJohn Baldwin * the nonce. 654*4361c4ebSJohn Baldwin */ 655*4361c4ebSJohn Baldwin L = 15 - nonce_length; 656*4361c4ebSJohn Baldwin 657*4361c4ebSJohn Baldwin flags = ((aad_length > 0) << 6) + 658*4361c4ebSJohn Baldwin (((tag_length - 2) / 2) << 3) + 659*4361c4ebSJohn Baldwin L - 1; 660*4361c4ebSJohn Baldwin 661*4361c4ebSJohn Baldwin /* 662*4361c4ebSJohn Baldwin * Now we need to set up the first block, which has flags, nonce, 663*4361c4ebSJohn Baldwin * and the message length. 664*4361c4ebSJohn Baldwin */ 665*4361c4ebSJohn Baldwin b0[0] = flags; 666*4361c4ebSJohn Baldwin memcpy(b0 + 1, nonce, nonce_length); 667*4361c4ebSJohn Baldwin bp = b0 + 1 + nonce_length; 668*4361c4ebSJohn Baldwin 669*4361c4ebSJohn Baldwin /* Need to copy L' [aka L-1] bytes of data_length */ 670*4361c4ebSJohn Baldwin for (uint8_t *dst = b0 + CCM_CBC_BLOCK_LEN - 1; dst >= bp; dst--) { 671*4361c4ebSJohn Baldwin *dst = data_length; 672*4361c4ebSJohn Baldwin data_length >>= 8; 673*4361c4ebSJohn Baldwin } 674*4361c4ebSJohn Baldwin } 675*4361c4ebSJohn Baldwin 676*4361c4ebSJohn Baldwin /* NB: OCF only supports AAD lengths < 2^32. */ 677*4361c4ebSJohn Baldwin static int 678*4361c4ebSJohn Baldwin build_ccm_aad_length(u_int aad_length, uint8_t *blk) 679*4361c4ebSJohn Baldwin { 680*4361c4ebSJohn Baldwin if (aad_length < ((1 << 16) - (1 << 8))) { 681*4361c4ebSJohn Baldwin be16enc(blk, aad_length); 682*4361c4ebSJohn Baldwin return (sizeof(uint16_t)); 683*4361c4ebSJohn Baldwin } else { 684*4361c4ebSJohn Baldwin blk[0] = 0xff; 685*4361c4ebSJohn Baldwin blk[1] = 0xfe; 686*4361c4ebSJohn Baldwin be32enc(blk + 2, aad_length); 687*4361c4ebSJohn Baldwin return (2 + sizeof(uint32_t)); 688*4361c4ebSJohn Baldwin } 689*4361c4ebSJohn Baldwin } 690*4361c4ebSJohn Baldwin 691c0341432SJohn Baldwin static int 692c0341432SJohn Baldwin swcr_ccm_cbc_mac(struct swcr_session *ses, struct cryptop *crp) 693c0341432SJohn Baldwin { 69426d292d3SJohn Baldwin u_char iv[AES_BLOCK_LEN]; 695*4361c4ebSJohn Baldwin u_char blk[CCM_CBC_BLOCK_LEN]; 696*4361c4ebSJohn Baldwin u_char tag[AES_CBC_MAC_HASH_LEN]; 697c0341432SJohn Baldwin union authctx ctx; 698ae18720dSJohn Baldwin const struct crypto_session_params *csp; 699c0341432SJohn Baldwin struct swcr_auth *swa; 700d8787d4fSMark Johnston const struct auth_hash *axf; 701*4361c4ebSJohn Baldwin int error, ivlen, len; 702c0341432SJohn Baldwin 703ae18720dSJohn Baldwin csp = crypto_get_params(crp->crp_session); 704c0341432SJohn Baldwin swa = &ses->swcr_auth; 705c0341432SJohn Baldwin axf = swa->sw_axf; 706c0341432SJohn Baldwin 707c0341432SJohn Baldwin bcopy(swa->sw_ictx, &ctx, axf->ctxsize); 708c0341432SJohn Baldwin 709c0341432SJohn Baldwin /* Initialize the IV */ 710ae18720dSJohn Baldwin ivlen = csp->csp_ivlen; 71129fe41ddSJohn Baldwin crypto_read_iv(crp, iv); 712c0341432SJohn Baldwin 713*4361c4ebSJohn Baldwin /* Supply MAC with IV */ 714*4361c4ebSJohn Baldwin axf->Reinit(&ctx, crp->crp_iv, ivlen); 715c0341432SJohn Baldwin 716*4361c4ebSJohn Baldwin /* Supply MAC with b0. */ 717*4361c4ebSJohn Baldwin build_ccm_b0(crp->crp_iv, ivlen, crp->crp_payload_length, 0, 718*4361c4ebSJohn Baldwin swa->sw_mlen, blk); 719*4361c4ebSJohn Baldwin axf->Update(&ctx, blk, CCM_CBC_BLOCK_LEN); 720*4361c4ebSJohn Baldwin 721*4361c4ebSJohn Baldwin len = build_ccm_aad_length(crp->crp_payload_length, blk); 722*4361c4ebSJohn Baldwin axf->Update(&ctx, blk, len); 723*4361c4ebSJohn Baldwin 724*4361c4ebSJohn Baldwin crypto_apply(crp, crp->crp_payload_start, crp->crp_payload_length, 725*4361c4ebSJohn Baldwin axf->Update, &ctx); 726c0341432SJohn Baldwin 727c0341432SJohn Baldwin /* Finalize MAC */ 72826d292d3SJohn Baldwin axf->Final(tag, &ctx); 729c0341432SJohn Baldwin 730*4361c4ebSJohn Baldwin error = 0; 731c0341432SJohn Baldwin if (crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) { 73226d292d3SJohn Baldwin u_char tag2[AES_CBC_MAC_HASH_LEN]; 73320c128daSJohn Baldwin 734c0341432SJohn Baldwin crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen, 73526d292d3SJohn Baldwin tag2); 73626d292d3SJohn Baldwin if (timingsafe_bcmp(tag, tag2, swa->sw_mlen) != 0) 73720c128daSJohn Baldwin error = EBADMSG; 73826d292d3SJohn Baldwin explicit_bzero(tag2, sizeof(tag)); 739c0341432SJohn Baldwin } else { 740c0341432SJohn Baldwin /* Inject the authentication data */ 74126d292d3SJohn Baldwin crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag); 742c0341432SJohn Baldwin } 74326d292d3SJohn Baldwin explicit_bzero(tag, sizeof(tag)); 744*4361c4ebSJohn Baldwin explicit_bzero(blk, sizeof(blk)); 74520c128daSJohn Baldwin explicit_bzero(iv, sizeof(iv)); 74620c128daSJohn Baldwin return (error); 747c0341432SJohn Baldwin } 748c0341432SJohn Baldwin 749c0341432SJohn Baldwin static int 750c0341432SJohn Baldwin swcr_ccm(struct swcr_session *ses, struct cryptop *crp) 751c0341432SJohn Baldwin { 752ae18720dSJohn Baldwin const struct crypto_session_params *csp; 75326d292d3SJohn Baldwin uint32_t blkbuf[howmany(AES_BLOCK_LEN, sizeof(uint32_t))]; 754c0341432SJohn Baldwin u_char *blk = (u_char *)blkbuf; 75526d292d3SJohn Baldwin u_char tag[AES_CBC_MAC_HASH_LEN]; 7569c0e3d3aSJohn Baldwin struct crypto_buffer_cursor cc_in, cc_out; 75726d292d3SJohn Baldwin const u_char *inblk; 75826d292d3SJohn Baldwin u_char *outblk; 759c0341432SJohn Baldwin union authctx ctx; 760c0341432SJohn Baldwin struct swcr_auth *swa; 761c0341432SJohn Baldwin struct swcr_encdec *swe; 762d8787d4fSMark Johnston const struct auth_hash *axf; 763d8787d4fSMark Johnston const struct enc_xform *exf; 76486be314dSJohn Baldwin size_t len; 76526d292d3SJohn Baldwin int blksz, error, ivlen, r, resid; 766c0341432SJohn Baldwin 767ae18720dSJohn Baldwin csp = crypto_get_params(crp->crp_session); 768c0341432SJohn Baldwin swa = &ses->swcr_auth; 769c0341432SJohn Baldwin axf = swa->sw_axf; 770c0341432SJohn Baldwin 771c0341432SJohn Baldwin bcopy(swa->sw_ictx, &ctx, axf->ctxsize); 77226d292d3SJohn Baldwin blksz = AES_BLOCK_LEN; 77326d292d3SJohn Baldwin KASSERT(axf->blocksize == blksz, ("%s: axf block size mismatch", 77426d292d3SJohn Baldwin __func__)); 775c0341432SJohn Baldwin 776c0341432SJohn Baldwin swe = &ses->swcr_encdec; 777c0341432SJohn Baldwin exf = swe->sw_exf; 778723d8764SJohn Baldwin KASSERT(axf->blocksize == exf->native_blocksize, 779723d8764SJohn Baldwin ("%s: blocksize mismatch", __func__)); 780c0341432SJohn Baldwin 781ae18720dSJohn Baldwin if (crp->crp_payload_length > ccm_max_payload_length(csp)) 782ae18720dSJohn Baldwin return (EMSGSIZE); 783ae18720dSJohn Baldwin 784c0341432SJohn Baldwin if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0) 785c0341432SJohn Baldwin return (EINVAL); 786c0341432SJohn Baldwin 787ae18720dSJohn Baldwin ivlen = csp->csp_ivlen; 788c0341432SJohn Baldwin 789c0341432SJohn Baldwin /* Supply MAC with IV */ 7905ae5ed5bSJohn Baldwin axf->Reinit(&ctx, crp->crp_iv, ivlen); 791c0341432SJohn Baldwin 792*4361c4ebSJohn Baldwin /* Supply MAC with b0. */ 793*4361c4ebSJohn Baldwin _Static_assert(sizeof(blkbuf) >= CCM_CBC_BLOCK_LEN, 794*4361c4ebSJohn Baldwin "blkbuf too small for b0"); 795*4361c4ebSJohn Baldwin build_ccm_b0(crp->crp_iv, ivlen, crp->crp_aad_length, 796*4361c4ebSJohn Baldwin crp->crp_payload_length, swa->sw_mlen, blk); 797*4361c4ebSJohn Baldwin axf->Update(&ctx, blk, CCM_CBC_BLOCK_LEN); 798*4361c4ebSJohn Baldwin 799c0341432SJohn Baldwin /* Supply MAC with AAD */ 800*4361c4ebSJohn Baldwin if (crp->crp_aad_length != 0) { 801*4361c4ebSJohn Baldwin len = build_ccm_aad_length(crp->crp_aad_length, blk); 802*4361c4ebSJohn Baldwin axf->Update(&ctx, blk, len); 8039b774dc0SJohn Baldwin if (crp->crp_aad != NULL) 804*4361c4ebSJohn Baldwin axf->Update(&ctx, crp->crp_aad, 805*4361c4ebSJohn Baldwin crp->crp_aad_length); 8069b774dc0SJohn Baldwin else 807*4361c4ebSJohn Baldwin crypto_apply(crp, crp->crp_aad_start, 8089b774dc0SJohn Baldwin crp->crp_aad_length, axf->Update, &ctx); 809*4361c4ebSJohn Baldwin 810*4361c4ebSJohn Baldwin /* Pad the AAD (including length field) to a full block. */ 811*4361c4ebSJohn Baldwin len = (len + crp->crp_aad_length) % CCM_CBC_BLOCK_LEN; 812*4361c4ebSJohn Baldwin if (len != 0) { 813*4361c4ebSJohn Baldwin len = CCM_CBC_BLOCK_LEN - len; 814*4361c4ebSJohn Baldwin memset(blk, 0, CCM_CBC_BLOCK_LEN); 815*4361c4ebSJohn Baldwin axf->Update(&ctx, blk, len); 816*4361c4ebSJohn Baldwin } 817*4361c4ebSJohn Baldwin } 818c0341432SJohn Baldwin 819a10020cfSJohn Baldwin if (crp->crp_cipher_key != NULL) 820a10020cfSJohn Baldwin exf->setkey(swe->sw_kschedule, crp->crp_cipher_key, 821a10020cfSJohn Baldwin crypto_get_params(crp->crp_session)->csp_cipher_klen); 8225ae5ed5bSJohn Baldwin exf->reinit(swe->sw_kschedule, crp->crp_iv, ivlen); 823c0341432SJohn Baldwin 824c0341432SJohn Baldwin /* Do encryption/decryption with MAC */ 8259c0e3d3aSJohn Baldwin crypto_cursor_init(&cc_in, &crp->crp_buf); 8269c0e3d3aSJohn Baldwin crypto_cursor_advance(&cc_in, crp->crp_payload_start); 8279c0e3d3aSJohn Baldwin if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) { 8289c0e3d3aSJohn Baldwin crypto_cursor_init(&cc_out, &crp->crp_obuf); 8299c0e3d3aSJohn Baldwin crypto_cursor_advance(&cc_out, crp->crp_payload_output_start); 8309c0e3d3aSJohn Baldwin } else 8319c0e3d3aSJohn Baldwin cc_out = cc_in; 83226d292d3SJohn Baldwin for (resid = crp->crp_payload_length; resid >= blksz; resid -= blksz) { 83386be314dSJohn Baldwin inblk = crypto_cursor_segment(&cc_in, &len); 83486be314dSJohn Baldwin if (len < blksz) { 83526d292d3SJohn Baldwin crypto_cursor_copydata(&cc_in, blksz, blk); 83626d292d3SJohn Baldwin inblk = blk; 83786be314dSJohn Baldwin } else 83826d292d3SJohn Baldwin crypto_cursor_advance(&cc_in, blksz); 839c0341432SJohn Baldwin if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { 84086be314dSJohn Baldwin outblk = crypto_cursor_segment(&cc_out, &len); 84186be314dSJohn Baldwin if (len < blksz) 84226d292d3SJohn Baldwin outblk = blk; 84326d292d3SJohn Baldwin axf->Update(&ctx, inblk, blksz); 84426d292d3SJohn Baldwin exf->encrypt(swe->sw_kschedule, inblk, outblk); 84526d292d3SJohn Baldwin if (outblk == blk) 84626d292d3SJohn Baldwin crypto_cursor_copyback(&cc_out, blksz, blk); 84726d292d3SJohn Baldwin else 84826d292d3SJohn Baldwin crypto_cursor_advance(&cc_out, blksz); 849c0341432SJohn Baldwin } else { 850c0341432SJohn Baldwin /* 851c0341432SJohn Baldwin * One of the problems with CCM+CBC is that 852c0341432SJohn Baldwin * the authentication is done on the 85326d292d3SJohn Baldwin * unencrypted data. As a result, we have to 854c0341432SJohn Baldwin * decrypt the data twice: once to generate 855c0341432SJohn Baldwin * the tag and a second time after the tag is 856c0341432SJohn Baldwin * verified. 857c0341432SJohn Baldwin */ 85826d292d3SJohn Baldwin exf->decrypt(swe->sw_kschedule, inblk, blk); 85926d292d3SJohn Baldwin axf->Update(&ctx, blk, blksz); 86026d292d3SJohn Baldwin } 86126d292d3SJohn Baldwin } 86226d292d3SJohn Baldwin if (resid > 0) { 86326d292d3SJohn Baldwin crypto_cursor_copydata(&cc_in, resid, blk); 86426d292d3SJohn Baldwin if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { 86526d292d3SJohn Baldwin axf->Update(&ctx, blk, resid); 86626d292d3SJohn Baldwin exf->encrypt_last(swe->sw_kschedule, blk, blk, resid); 86726d292d3SJohn Baldwin crypto_cursor_copyback(&cc_out, resid, blk); 86826d292d3SJohn Baldwin } else { 86926d292d3SJohn Baldwin exf->decrypt_last(swe->sw_kschedule, blk, blk, resid); 87026d292d3SJohn Baldwin axf->Update(&ctx, blk, resid); 871c0341432SJohn Baldwin } 87208fca7a5SJohn-Mark Gurney } 87308fca7a5SJohn-Mark Gurney 87408fca7a5SJohn-Mark Gurney /* Finalize MAC */ 87526d292d3SJohn Baldwin axf->Final(tag, &ctx); 87608fca7a5SJohn-Mark Gurney 87708fca7a5SJohn-Mark Gurney /* Validate tag */ 87820c128daSJohn Baldwin error = 0; 879c0341432SJohn Baldwin if (!CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { 88026d292d3SJohn Baldwin u_char tag2[AES_CBC_MAC_HASH_LEN]; 88120c128daSJohn Baldwin 882c0341432SJohn Baldwin crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen, 88326d292d3SJohn Baldwin tag2); 88408fca7a5SJohn-Mark Gurney 88526d292d3SJohn Baldwin r = timingsafe_bcmp(tag, tag2, swa->sw_mlen); 88626d292d3SJohn Baldwin explicit_bzero(tag2, sizeof(tag2)); 88720c128daSJohn Baldwin if (r != 0) { 88820c128daSJohn Baldwin error = EBADMSG; 88920c128daSJohn Baldwin goto out; 89020c128daSJohn Baldwin } 891c0341432SJohn Baldwin 89208fca7a5SJohn-Mark Gurney /* tag matches, decrypt data */ 8935ae5ed5bSJohn Baldwin exf->reinit(swe->sw_kschedule, crp->crp_iv, ivlen); 8949c0e3d3aSJohn Baldwin crypto_cursor_init(&cc_in, &crp->crp_buf); 8959c0e3d3aSJohn Baldwin crypto_cursor_advance(&cc_in, crp->crp_payload_start); 89626d292d3SJohn Baldwin for (resid = crp->crp_payload_length; resid > blksz; 89726d292d3SJohn Baldwin resid -= blksz) { 89886be314dSJohn Baldwin inblk = crypto_cursor_segment(&cc_in, &len); 89986be314dSJohn Baldwin if (len < blksz) { 90026d292d3SJohn Baldwin crypto_cursor_copydata(&cc_in, blksz, blk); 90126d292d3SJohn Baldwin inblk = blk; 90286be314dSJohn Baldwin } else 90326d292d3SJohn Baldwin crypto_cursor_advance(&cc_in, blksz); 90486be314dSJohn Baldwin outblk = crypto_cursor_segment(&cc_out, &len); 90586be314dSJohn Baldwin if (len < blksz) 90626d292d3SJohn Baldwin outblk = blk; 90726d292d3SJohn Baldwin exf->decrypt(swe->sw_kschedule, inblk, outblk); 90826d292d3SJohn Baldwin if (outblk == blk) 90926d292d3SJohn Baldwin crypto_cursor_copyback(&cc_out, blksz, blk); 91026d292d3SJohn Baldwin else 91126d292d3SJohn Baldwin crypto_cursor_advance(&cc_out, blksz); 91226d292d3SJohn Baldwin } 91326d292d3SJohn Baldwin if (resid > 0) { 91426d292d3SJohn Baldwin crypto_cursor_copydata(&cc_in, resid, blk); 91526d292d3SJohn Baldwin exf->decrypt_last(swe->sw_kschedule, blk, blk, resid); 91626d292d3SJohn Baldwin crypto_cursor_copyback(&cc_out, resid, blk); 91708fca7a5SJohn-Mark Gurney } 91808fca7a5SJohn-Mark Gurney } else { 91908fca7a5SJohn-Mark Gurney /* Inject the authentication data */ 92026d292d3SJohn Baldwin crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag); 92108fca7a5SJohn-Mark Gurney } 92208fca7a5SJohn-Mark Gurney 92320c128daSJohn Baldwin out: 92420c128daSJohn Baldwin explicit_bzero(blkbuf, sizeof(blkbuf)); 92526d292d3SJohn Baldwin explicit_bzero(tag, sizeof(tag)); 92620c128daSJohn Baldwin return (error); 92708fca7a5SJohn-Mark Gurney } 92808fca7a5SJohn-Mark Gurney 929dd2e1352SJohn Baldwin static int 930dd2e1352SJohn Baldwin swcr_chacha20_poly1305(struct swcr_session *ses, struct cryptop *crp) 931dd2e1352SJohn Baldwin { 932dd2e1352SJohn Baldwin const struct crypto_session_params *csp; 933dd2e1352SJohn Baldwin uint64_t blkbuf[howmany(CHACHA20_NATIVE_BLOCK_LEN, sizeof(uint64_t))]; 934dd2e1352SJohn Baldwin u_char *blk = (u_char *)blkbuf; 935dd2e1352SJohn Baldwin u_char tag[POLY1305_HASH_LEN]; 936dd2e1352SJohn Baldwin struct crypto_buffer_cursor cc_in, cc_out; 937dd2e1352SJohn Baldwin const u_char *inblk; 938dd2e1352SJohn Baldwin u_char *outblk; 939dd2e1352SJohn Baldwin uint64_t *blkp; 940dd2e1352SJohn Baldwin union authctx ctx; 941dd2e1352SJohn Baldwin struct swcr_auth *swa; 942dd2e1352SJohn Baldwin struct swcr_encdec *swe; 943d8787d4fSMark Johnston const struct auth_hash *axf; 944d8787d4fSMark Johnston const struct enc_xform *exf; 94586be314dSJohn Baldwin size_t len; 946dd2e1352SJohn Baldwin int blksz, error, r, resid; 947dd2e1352SJohn Baldwin 948dd2e1352SJohn Baldwin swa = &ses->swcr_auth; 949dd2e1352SJohn Baldwin axf = swa->sw_axf; 950dd2e1352SJohn Baldwin 951dd2e1352SJohn Baldwin swe = &ses->swcr_encdec; 952dd2e1352SJohn Baldwin exf = swe->sw_exf; 953dd2e1352SJohn Baldwin blksz = exf->native_blocksize; 954dd2e1352SJohn Baldwin KASSERT(blksz <= sizeof(blkbuf), ("%s: blocksize mismatch", __func__)); 955dd2e1352SJohn Baldwin 956dd2e1352SJohn Baldwin if ((crp->crp_flags & CRYPTO_F_IV_SEPARATE) == 0) 957dd2e1352SJohn Baldwin return (EINVAL); 958dd2e1352SJohn Baldwin 959dd2e1352SJohn Baldwin csp = crypto_get_params(crp->crp_session); 960dd2e1352SJohn Baldwin 961dd2e1352SJohn Baldwin /* Generate Poly1305 key. */ 962dd2e1352SJohn Baldwin if (crp->crp_cipher_key != NULL) 963dd2e1352SJohn Baldwin axf->Setkey(&ctx, crp->crp_cipher_key, csp->csp_cipher_klen); 964dd2e1352SJohn Baldwin else 965dd2e1352SJohn Baldwin axf->Setkey(&ctx, csp->csp_cipher_key, csp->csp_cipher_klen); 966dd2e1352SJohn Baldwin axf->Reinit(&ctx, crp->crp_iv, csp->csp_ivlen); 967dd2e1352SJohn Baldwin 968dd2e1352SJohn Baldwin /* Supply MAC with AAD */ 969dd2e1352SJohn Baldwin if (crp->crp_aad != NULL) 970dd2e1352SJohn Baldwin axf->Update(&ctx, crp->crp_aad, crp->crp_aad_length); 971dd2e1352SJohn Baldwin else 972dd2e1352SJohn Baldwin crypto_apply(crp, crp->crp_aad_start, 973dd2e1352SJohn Baldwin crp->crp_aad_length, axf->Update, &ctx); 974dd2e1352SJohn Baldwin if (crp->crp_aad_length % 16 != 0) { 975dd2e1352SJohn Baldwin /* padding1 */ 976dd2e1352SJohn Baldwin memset(blk, 0, 16); 977dd2e1352SJohn Baldwin axf->Update(&ctx, blk, 16 - crp->crp_aad_length % 16); 978dd2e1352SJohn Baldwin } 979dd2e1352SJohn Baldwin 980dd2e1352SJohn Baldwin if (crp->crp_cipher_key != NULL) 981dd2e1352SJohn Baldwin exf->setkey(swe->sw_kschedule, crp->crp_cipher_key, 982dd2e1352SJohn Baldwin csp->csp_cipher_klen); 9831833d604SJohn Baldwin exf->reinit(swe->sw_kschedule, crp->crp_iv, csp->csp_ivlen); 984dd2e1352SJohn Baldwin 985dd2e1352SJohn Baldwin /* Do encryption with MAC */ 986dd2e1352SJohn Baldwin crypto_cursor_init(&cc_in, &crp->crp_buf); 987dd2e1352SJohn Baldwin crypto_cursor_advance(&cc_in, crp->crp_payload_start); 988dd2e1352SJohn Baldwin if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) { 989dd2e1352SJohn Baldwin crypto_cursor_init(&cc_out, &crp->crp_obuf); 990dd2e1352SJohn Baldwin crypto_cursor_advance(&cc_out, crp->crp_payload_output_start); 991dd2e1352SJohn Baldwin } else 992dd2e1352SJohn Baldwin cc_out = cc_in; 993dd2e1352SJohn Baldwin for (resid = crp->crp_payload_length; resid >= blksz; resid -= blksz) { 99486be314dSJohn Baldwin inblk = crypto_cursor_segment(&cc_in, &len); 99586be314dSJohn Baldwin if (len < blksz) { 996dd2e1352SJohn Baldwin crypto_cursor_copydata(&cc_in, blksz, blk); 997dd2e1352SJohn Baldwin inblk = blk; 99886be314dSJohn Baldwin } else 999dd2e1352SJohn Baldwin crypto_cursor_advance(&cc_in, blksz); 1000dd2e1352SJohn Baldwin if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { 100186be314dSJohn Baldwin outblk = crypto_cursor_segment(&cc_out, &len); 100286be314dSJohn Baldwin if (len < blksz) 1003dd2e1352SJohn Baldwin outblk = blk; 1004dd2e1352SJohn Baldwin exf->encrypt(swe->sw_kschedule, inblk, outblk); 1005dd2e1352SJohn Baldwin axf->Update(&ctx, outblk, blksz); 1006dd2e1352SJohn Baldwin if (outblk == blk) 1007dd2e1352SJohn Baldwin crypto_cursor_copyback(&cc_out, blksz, blk); 1008dd2e1352SJohn Baldwin else 1009dd2e1352SJohn Baldwin crypto_cursor_advance(&cc_out, blksz); 1010dd2e1352SJohn Baldwin } else { 1011dd2e1352SJohn Baldwin axf->Update(&ctx, inblk, blksz); 1012dd2e1352SJohn Baldwin } 1013dd2e1352SJohn Baldwin } 1014dd2e1352SJohn Baldwin if (resid > 0) { 1015dd2e1352SJohn Baldwin crypto_cursor_copydata(&cc_in, resid, blk); 1016dd2e1352SJohn Baldwin if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { 1017dd2e1352SJohn Baldwin exf->encrypt_last(swe->sw_kschedule, blk, blk, resid); 1018dd2e1352SJohn Baldwin crypto_cursor_copyback(&cc_out, resid, blk); 1019dd2e1352SJohn Baldwin } 1020dd2e1352SJohn Baldwin axf->Update(&ctx, blk, resid); 1021dd2e1352SJohn Baldwin if (resid % 16 != 0) { 1022dd2e1352SJohn Baldwin /* padding2 */ 1023dd2e1352SJohn Baldwin memset(blk, 0, 16); 1024dd2e1352SJohn Baldwin axf->Update(&ctx, blk, 16 - resid % 16); 1025dd2e1352SJohn Baldwin } 1026dd2e1352SJohn Baldwin } 1027dd2e1352SJohn Baldwin 1028dd2e1352SJohn Baldwin /* lengths */ 1029dd2e1352SJohn Baldwin blkp = (uint64_t *)blk; 1030dd2e1352SJohn Baldwin blkp[0] = htole64(crp->crp_aad_length); 1031dd2e1352SJohn Baldwin blkp[1] = htole64(crp->crp_payload_length); 1032dd2e1352SJohn Baldwin axf->Update(&ctx, blk, sizeof(uint64_t) * 2); 1033dd2e1352SJohn Baldwin 1034dd2e1352SJohn Baldwin /* Finalize MAC */ 1035dd2e1352SJohn Baldwin axf->Final(tag, &ctx); 1036dd2e1352SJohn Baldwin 1037dd2e1352SJohn Baldwin /* Validate tag */ 1038dd2e1352SJohn Baldwin error = 0; 1039dd2e1352SJohn Baldwin if (!CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { 1040dd2e1352SJohn Baldwin u_char tag2[POLY1305_HASH_LEN]; 1041dd2e1352SJohn Baldwin 1042dd2e1352SJohn Baldwin crypto_copydata(crp, crp->crp_digest_start, swa->sw_mlen, tag2); 1043dd2e1352SJohn Baldwin 1044dd2e1352SJohn Baldwin r = timingsafe_bcmp(tag, tag2, swa->sw_mlen); 1045dd2e1352SJohn Baldwin explicit_bzero(tag2, sizeof(tag2)); 1046dd2e1352SJohn Baldwin if (r != 0) { 1047dd2e1352SJohn Baldwin error = EBADMSG; 1048dd2e1352SJohn Baldwin goto out; 1049dd2e1352SJohn Baldwin } 1050dd2e1352SJohn Baldwin 1051dd2e1352SJohn Baldwin /* tag matches, decrypt data */ 1052dd2e1352SJohn Baldwin crypto_cursor_init(&cc_in, &crp->crp_buf); 1053dd2e1352SJohn Baldwin crypto_cursor_advance(&cc_in, crp->crp_payload_start); 1054dd2e1352SJohn Baldwin for (resid = crp->crp_payload_length; resid > blksz; 1055dd2e1352SJohn Baldwin resid -= blksz) { 105686be314dSJohn Baldwin inblk = crypto_cursor_segment(&cc_in, &len); 105786be314dSJohn Baldwin if (len < blksz) { 1058dd2e1352SJohn Baldwin crypto_cursor_copydata(&cc_in, blksz, blk); 1059dd2e1352SJohn Baldwin inblk = blk; 106086be314dSJohn Baldwin } else 1061dd2e1352SJohn Baldwin crypto_cursor_advance(&cc_in, blksz); 106286be314dSJohn Baldwin outblk = crypto_cursor_segment(&cc_out, &len); 106386be314dSJohn Baldwin if (len < blksz) 1064dd2e1352SJohn Baldwin outblk = blk; 1065dd2e1352SJohn Baldwin exf->decrypt(swe->sw_kschedule, inblk, outblk); 1066dd2e1352SJohn Baldwin if (outblk == blk) 1067dd2e1352SJohn Baldwin crypto_cursor_copyback(&cc_out, blksz, blk); 1068dd2e1352SJohn Baldwin else 1069dd2e1352SJohn Baldwin crypto_cursor_advance(&cc_out, blksz); 1070dd2e1352SJohn Baldwin } 1071dd2e1352SJohn Baldwin if (resid > 0) { 1072dd2e1352SJohn Baldwin crypto_cursor_copydata(&cc_in, resid, blk); 1073dd2e1352SJohn Baldwin exf->decrypt_last(swe->sw_kschedule, blk, blk, resid); 1074dd2e1352SJohn Baldwin crypto_cursor_copyback(&cc_out, resid, blk); 1075dd2e1352SJohn Baldwin } 1076dd2e1352SJohn Baldwin } else { 1077dd2e1352SJohn Baldwin /* Inject the authentication data */ 1078dd2e1352SJohn Baldwin crypto_copyback(crp, crp->crp_digest_start, swa->sw_mlen, tag); 1079dd2e1352SJohn Baldwin } 1080dd2e1352SJohn Baldwin 1081dd2e1352SJohn Baldwin out: 1082dd2e1352SJohn Baldwin explicit_bzero(blkbuf, sizeof(blkbuf)); 1083dd2e1352SJohn Baldwin explicit_bzero(tag, sizeof(tag)); 1084dd2e1352SJohn Baldwin explicit_bzero(&ctx, sizeof(ctx)); 1085dd2e1352SJohn Baldwin return (error); 1086dd2e1352SJohn Baldwin } 1087dd2e1352SJohn Baldwin 1088091d81d1SSam Leffler /* 1089c0341432SJohn Baldwin * Apply a cipher and a digest to perform EtA. 1090c0341432SJohn Baldwin */ 1091c0341432SJohn Baldwin static int 1092c0341432SJohn Baldwin swcr_eta(struct swcr_session *ses, struct cryptop *crp) 1093c0341432SJohn Baldwin { 1094c0341432SJohn Baldwin int error; 1095c0341432SJohn Baldwin 1096c0341432SJohn Baldwin if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op)) { 1097c0341432SJohn Baldwin error = swcr_encdec(ses, crp); 1098c0341432SJohn Baldwin if (error == 0) 1099c0341432SJohn Baldwin error = swcr_authcompute(ses, crp); 1100c0341432SJohn Baldwin } else { 1101c0341432SJohn Baldwin error = swcr_authcompute(ses, crp); 1102c0341432SJohn Baldwin if (error == 0) 1103c0341432SJohn Baldwin error = swcr_encdec(ses, crp); 1104c0341432SJohn Baldwin } 1105c0341432SJohn Baldwin return (error); 1106c0341432SJohn Baldwin } 1107c0341432SJohn Baldwin 1108c0341432SJohn Baldwin /* 1109091d81d1SSam Leffler * Apply a compression/decompression algorithm 1110091d81d1SSam Leffler */ 1111091d81d1SSam Leffler static int 1112c0341432SJohn Baldwin swcr_compdec(struct swcr_session *ses, struct cryptop *crp) 1113091d81d1SSam Leffler { 1114d8787d4fSMark Johnston const struct comp_algo *cxf; 1115d3d79e96SJohn Baldwin uint8_t *data, *out; 1116091d81d1SSam Leffler int adj; 1117d3d79e96SJohn Baldwin uint32_t result; 1118091d81d1SSam Leffler 1119c0341432SJohn Baldwin cxf = ses->swcr_compdec.sw_cxf; 1120091d81d1SSam Leffler 1121091d81d1SSam Leffler /* We must handle the whole buffer of data in one time 1122091d81d1SSam Leffler * then if there is not all the data in the mbuf, we must 1123091d81d1SSam Leffler * copy in a buffer. 1124091d81d1SSam Leffler */ 1125091d81d1SSam Leffler 1126c0341432SJohn Baldwin data = malloc(crp->crp_payload_length, M_CRYPTO_DATA, M_NOWAIT); 1127091d81d1SSam Leffler if (data == NULL) 1128091d81d1SSam Leffler return (EINVAL); 1129c0341432SJohn Baldwin crypto_copydata(crp, crp->crp_payload_start, crp->crp_payload_length, 1130c0341432SJohn Baldwin data); 1131091d81d1SSam Leffler 1132c0341432SJohn Baldwin if (CRYPTO_OP_IS_COMPRESS(crp->crp_op)) 1133c0341432SJohn Baldwin result = cxf->compress(data, crp->crp_payload_length, &out); 1134091d81d1SSam Leffler else 1135c0341432SJohn Baldwin result = cxf->decompress(data, crp->crp_payload_length, &out); 1136091d81d1SSam Leffler 11371ede983cSDag-Erling Smørgrav free(data, M_CRYPTO_DATA); 1138091d81d1SSam Leffler if (result == 0) 1139c0341432SJohn Baldwin return (EINVAL); 1140c0341432SJohn Baldwin crp->crp_olen = result; 1141c0341432SJohn Baldwin 1142c0341432SJohn Baldwin /* Check the compressed size when doing compression */ 1143c0341432SJohn Baldwin if (CRYPTO_OP_IS_COMPRESS(crp->crp_op)) { 1144c0341432SJohn Baldwin if (result >= crp->crp_payload_length) { 1145c0341432SJohn Baldwin /* Compression was useless, we lost time */ 1146c0341432SJohn Baldwin free(out, M_CRYPTO_DATA); 1147c0341432SJohn Baldwin return (0); 1148c0341432SJohn Baldwin } 1149c0341432SJohn Baldwin } 1150091d81d1SSam Leffler 1151091d81d1SSam Leffler /* Copy back the (de)compressed data. m_copyback is 1152091d81d1SSam Leffler * extending the mbuf as necessary. 1153091d81d1SSam Leffler */ 1154c0341432SJohn Baldwin crypto_copyback(crp, crp->crp_payload_start, result, out); 1155c0341432SJohn Baldwin if (result < crp->crp_payload_length) { 11569c0e3d3aSJohn Baldwin switch (crp->crp_buf.cb_type) { 1157c0341432SJohn Baldwin case CRYPTO_BUF_MBUF: 1158883a0196SJohn Baldwin case CRYPTO_BUF_SINGLE_MBUF: 1159c0341432SJohn Baldwin adj = result - crp->crp_payload_length; 11609c0e3d3aSJohn Baldwin m_adj(crp->crp_buf.cb_mbuf, adj); 1161c0341432SJohn Baldwin break; 1162c0341432SJohn Baldwin case CRYPTO_BUF_UIO: { 11639c0e3d3aSJohn Baldwin struct uio *uio = crp->crp_buf.cb_uio; 1164091d81d1SSam Leffler int ind; 1165091d81d1SSam Leffler 1166c0341432SJohn Baldwin adj = crp->crp_payload_length - result; 1167091d81d1SSam Leffler ind = uio->uio_iovcnt - 1; 1168091d81d1SSam Leffler 1169091d81d1SSam Leffler while (adj > 0 && ind >= 0) { 1170091d81d1SSam Leffler if (adj < uio->uio_iov[ind].iov_len) { 1171091d81d1SSam Leffler uio->uio_iov[ind].iov_len -= adj; 1172091d81d1SSam Leffler break; 1173091d81d1SSam Leffler } 1174091d81d1SSam Leffler 1175091d81d1SSam Leffler adj -= uio->uio_iov[ind].iov_len; 1176091d81d1SSam Leffler uio->uio_iov[ind].iov_len = 0; 1177091d81d1SSam Leffler ind--; 1178091d81d1SSam Leffler uio->uio_iovcnt--; 1179091d81d1SSam Leffler } 1180091d81d1SSam Leffler } 1181c0341432SJohn Baldwin break; 1182e6f6d0c9SAlan Somers case CRYPTO_BUF_VMPAGE: 1183e6f6d0c9SAlan Somers adj = crp->crp_payload_length - result; 1184e6f6d0c9SAlan Somers crp->crp_buf.cb_vm_page_len -= adj; 1185e6f6d0c9SAlan Somers break; 11869c0e3d3aSJohn Baldwin default: 11879c0e3d3aSJohn Baldwin break; 1188c0341432SJohn Baldwin } 1189091d81d1SSam Leffler } 11901ede983cSDag-Erling Smørgrav free(out, M_CRYPTO_DATA); 1191091d81d1SSam Leffler return 0; 1192091d81d1SSam Leffler } 1193091d81d1SSam Leffler 1194091d81d1SSam Leffler static int 11953e947048SJohn Baldwin swcr_setup_cipher(struct swcr_session *ses, 1196c0341432SJohn Baldwin const struct crypto_session_params *csp) 1197091d81d1SSam Leffler { 1198c0341432SJohn Baldwin struct swcr_encdec *swe; 1199d8787d4fSMark Johnston const struct enc_xform *txf; 1200f6c4bc3bSPawel Jakub Dawidek int error; 1201091d81d1SSam Leffler 1202c0341432SJohn Baldwin swe = &ses->swcr_encdec; 1203c0341432SJohn Baldwin txf = crypto_cipher(csp); 12043e947048SJohn Baldwin if (txf->ctxsize != 0) { 12053e947048SJohn Baldwin swe->sw_kschedule = malloc(txf->ctxsize, M_CRYPTO_DATA, 12063e947048SJohn Baldwin M_NOWAIT); 12073e947048SJohn Baldwin if (swe->sw_kschedule == NULL) 12083e947048SJohn Baldwin return (ENOMEM); 12093e947048SJohn Baldwin } 1210c0341432SJohn Baldwin if (csp->csp_cipher_key != NULL) { 12113e947048SJohn Baldwin error = txf->setkey(swe->sw_kschedule, 1212c0341432SJohn Baldwin csp->csp_cipher_key, csp->csp_cipher_klen); 1213c0341432SJohn Baldwin if (error) 1214c0341432SJohn Baldwin return (error); 1215091d81d1SSam Leffler } 1216c0341432SJohn Baldwin swe->sw_exf = txf; 1217c0341432SJohn Baldwin return (0); 1218f6c4bc3bSPawel Jakub Dawidek } 1219091d81d1SSam Leffler 1220c0341432SJohn Baldwin static int 1221c0341432SJohn Baldwin swcr_setup_auth(struct swcr_session *ses, 1222c0341432SJohn Baldwin const struct crypto_session_params *csp) 1223c0341432SJohn Baldwin { 1224c0341432SJohn Baldwin struct swcr_auth *swa; 1225d8787d4fSMark Johnston const struct auth_hash *axf; 1226c0341432SJohn Baldwin 1227c0341432SJohn Baldwin swa = &ses->swcr_auth; 1228c0341432SJohn Baldwin 1229c0341432SJohn Baldwin axf = crypto_auth_hash(csp); 1230c0341432SJohn Baldwin swa->sw_axf = axf; 1231c0341432SJohn Baldwin if (csp->csp_auth_mlen < 0 || csp->csp_auth_mlen > axf->hashsize) 1232c0341432SJohn Baldwin return (EINVAL); 1233c0341432SJohn Baldwin if (csp->csp_auth_mlen == 0) 1234c0341432SJohn Baldwin swa->sw_mlen = axf->hashsize; 1235c0341432SJohn Baldwin else 1236c0341432SJohn Baldwin swa->sw_mlen = csp->csp_auth_mlen; 1237c0341432SJohn Baldwin swa->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); 1238c0341432SJohn Baldwin if (swa->sw_ictx == NULL) 1239c0341432SJohn Baldwin return (ENOBUFS); 1240c0341432SJohn Baldwin 1241c0341432SJohn Baldwin switch (csp->csp_auth_alg) { 1242091d81d1SSam Leffler case CRYPTO_SHA1_HMAC: 1243c97f39ceSConrad Meyer case CRYPTO_SHA2_224_HMAC: 1244f6c4bc3bSPawel Jakub Dawidek case CRYPTO_SHA2_256_HMAC: 1245f6c4bc3bSPawel Jakub Dawidek case CRYPTO_SHA2_384_HMAC: 1246f6c4bc3bSPawel Jakub Dawidek case CRYPTO_SHA2_512_HMAC: 1247091d81d1SSam Leffler case CRYPTO_NULL_HMAC: 1248091d81d1SSam Leffler case CRYPTO_RIPEMD160_HMAC: 12493a0b6a93SJohn Baldwin swa->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA, 1250091d81d1SSam Leffler M_NOWAIT); 1251c0341432SJohn Baldwin if (swa->sw_octx == NULL) 1252c0341432SJohn Baldwin return (ENOBUFS); 1253c0341432SJohn Baldwin 1254c0341432SJohn Baldwin if (csp->csp_auth_key != NULL) { 1255c0341432SJohn Baldwin swcr_authprepare(axf, swa, csp->csp_auth_key, 1256c0341432SJohn Baldwin csp->csp_auth_klen); 1257091d81d1SSam Leffler } 1258091d81d1SSam Leffler 1259c0341432SJohn Baldwin if (csp->csp_mode == CSP_MODE_DIGEST) 1260c0341432SJohn Baldwin ses->swcr_process = swcr_authcompute; 1261091d81d1SSam Leffler break; 1262091d81d1SSam Leffler case CRYPTO_SHA1: 1263c4729f6eSConrad Meyer case CRYPTO_SHA2_224: 1264c4729f6eSConrad Meyer case CRYPTO_SHA2_256: 1265c4729f6eSConrad Meyer case CRYPTO_SHA2_384: 1266c4729f6eSConrad Meyer case CRYPTO_SHA2_512: 1267c0341432SJohn Baldwin axf->Init(swa->sw_ictx); 1268c0341432SJohn Baldwin if (csp->csp_mode == CSP_MODE_DIGEST) 1269c0341432SJohn Baldwin ses->swcr_process = swcr_authcompute; 1270c0341432SJohn Baldwin break; 1271c0341432SJohn Baldwin case CRYPTO_AES_NIST_GMAC: 1272c0341432SJohn Baldwin axf->Init(swa->sw_ictx); 1273c0341432SJohn Baldwin axf->Setkey(swa->sw_ictx, csp->csp_auth_key, 1274c0341432SJohn Baldwin csp->csp_auth_klen); 1275c0341432SJohn Baldwin if (csp->csp_mode == CSP_MODE_DIGEST) 1276c0341432SJohn Baldwin ses->swcr_process = swcr_gmac; 1277c0341432SJohn Baldwin break; 1278c0341432SJohn Baldwin case CRYPTO_POLY1305: 1279c0341432SJohn Baldwin case CRYPTO_BLAKE2B: 1280c0341432SJohn Baldwin case CRYPTO_BLAKE2S: 1281c0341432SJohn Baldwin /* 1282c0341432SJohn Baldwin * Blake2b and Blake2s support an optional key but do 1283c0341432SJohn Baldwin * not require one. 1284c0341432SJohn Baldwin */ 1285c0341432SJohn Baldwin if (csp->csp_auth_klen == 0 || csp->csp_auth_key != NULL) 1286c0341432SJohn Baldwin axf->Setkey(swa->sw_ictx, csp->csp_auth_key, 1287c0341432SJohn Baldwin csp->csp_auth_klen); 1288c0341432SJohn Baldwin axf->Init(swa->sw_ictx); 1289c0341432SJohn Baldwin if (csp->csp_mode == CSP_MODE_DIGEST) 1290c0341432SJohn Baldwin ses->swcr_process = swcr_authcompute; 1291c0341432SJohn Baldwin break; 1292c0341432SJohn Baldwin case CRYPTO_AES_CCM_CBC_MAC: 1293c0341432SJohn Baldwin axf->Init(swa->sw_ictx); 1294c0341432SJohn Baldwin axf->Setkey(swa->sw_ictx, csp->csp_auth_key, 1295c0341432SJohn Baldwin csp->csp_auth_klen); 1296c0341432SJohn Baldwin if (csp->csp_mode == CSP_MODE_DIGEST) 1297c0341432SJohn Baldwin ses->swcr_process = swcr_ccm_cbc_mac; 1298c0341432SJohn Baldwin break; 1299091d81d1SSam Leffler } 1300091d81d1SSam Leffler 1301c0341432SJohn Baldwin return (0); 1302c0341432SJohn Baldwin } 130308fca7a5SJohn-Mark Gurney 1304c0341432SJohn Baldwin static int 1305c0341432SJohn Baldwin swcr_setup_gcm(struct swcr_session *ses, 1306c0341432SJohn Baldwin const struct crypto_session_params *csp) 1307c0341432SJohn Baldwin { 1308c0341432SJohn Baldwin struct swcr_auth *swa; 1309d8787d4fSMark Johnston const struct auth_hash *axf; 1310c0341432SJohn Baldwin 1311c0341432SJohn Baldwin if (csp->csp_ivlen != AES_GCM_IV_LEN) 1312c0341432SJohn Baldwin return (EINVAL); 1313c0341432SJohn Baldwin 1314c0341432SJohn Baldwin /* First, setup the auth side. */ 1315c0341432SJohn Baldwin swa = &ses->swcr_auth; 1316c0341432SJohn Baldwin switch (csp->csp_cipher_klen * 8) { 1317c0341432SJohn Baldwin case 128: 1318c0341432SJohn Baldwin axf = &auth_hash_nist_gmac_aes_128; 1319c0341432SJohn Baldwin break; 1320c0341432SJohn Baldwin case 192: 1321c0341432SJohn Baldwin axf = &auth_hash_nist_gmac_aes_192; 1322c0341432SJohn Baldwin break; 1323c0341432SJohn Baldwin case 256: 1324c0341432SJohn Baldwin axf = &auth_hash_nist_gmac_aes_256; 1325c0341432SJohn Baldwin break; 1326c0341432SJohn Baldwin default: 1327c0341432SJohn Baldwin return (EINVAL); 1328c0341432SJohn Baldwin } 1329c0341432SJohn Baldwin swa->sw_axf = axf; 1330c0341432SJohn Baldwin if (csp->csp_auth_mlen < 0 || csp->csp_auth_mlen > axf->hashsize) 1331c0341432SJohn Baldwin return (EINVAL); 1332c0341432SJohn Baldwin if (csp->csp_auth_mlen == 0) 1333c0341432SJohn Baldwin swa->sw_mlen = axf->hashsize; 1334c0341432SJohn Baldwin else 1335c0341432SJohn Baldwin swa->sw_mlen = csp->csp_auth_mlen; 1336c0341432SJohn Baldwin swa->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); 1337c0341432SJohn Baldwin if (swa->sw_ictx == NULL) 1338c0341432SJohn Baldwin return (ENOBUFS); 1339c0341432SJohn Baldwin axf->Init(swa->sw_ictx); 1340c0341432SJohn Baldwin if (csp->csp_cipher_key != NULL) 1341c0341432SJohn Baldwin axf->Setkey(swa->sw_ictx, csp->csp_cipher_key, 1342c0341432SJohn Baldwin csp->csp_cipher_klen); 1343c0341432SJohn Baldwin 1344c0341432SJohn Baldwin /* Second, setup the cipher side. */ 13453e947048SJohn Baldwin return (swcr_setup_cipher(ses, csp)); 1346c0341432SJohn Baldwin } 1347c0341432SJohn Baldwin 1348c0341432SJohn Baldwin static int 1349c0341432SJohn Baldwin swcr_setup_ccm(struct swcr_session *ses, 1350c0341432SJohn Baldwin const struct crypto_session_params *csp) 1351c0341432SJohn Baldwin { 1352c0341432SJohn Baldwin struct swcr_auth *swa; 1353d8787d4fSMark Johnston const struct auth_hash *axf; 1354c0341432SJohn Baldwin 1355c0341432SJohn Baldwin /* First, setup the auth side. */ 1356c0341432SJohn Baldwin swa = &ses->swcr_auth; 1357c0341432SJohn Baldwin switch (csp->csp_cipher_klen * 8) { 1358507281e5SSean Eric Fagan case 128: 1359507281e5SSean Eric Fagan axf = &auth_hash_ccm_cbc_mac_128; 1360507281e5SSean Eric Fagan break; 1361507281e5SSean Eric Fagan case 192: 1362507281e5SSean Eric Fagan axf = &auth_hash_ccm_cbc_mac_192; 1363507281e5SSean Eric Fagan break; 1364507281e5SSean Eric Fagan case 256: 1365507281e5SSean Eric Fagan axf = &auth_hash_ccm_cbc_mac_256; 1366507281e5SSean Eric Fagan break; 1367507281e5SSean Eric Fagan default: 1368c0341432SJohn Baldwin return (EINVAL); 1369507281e5SSean Eric Fagan } 1370c0341432SJohn Baldwin swa->sw_axf = axf; 1371c0341432SJohn Baldwin if (csp->csp_auth_mlen < 0 || csp->csp_auth_mlen > axf->hashsize) 1372c0341432SJohn Baldwin return (EINVAL); 1373c0341432SJohn Baldwin if (csp->csp_auth_mlen == 0) 1374c0341432SJohn Baldwin swa->sw_mlen = axf->hashsize; 1375c0341432SJohn Baldwin else 1376c0341432SJohn Baldwin swa->sw_mlen = csp->csp_auth_mlen; 1377c0341432SJohn Baldwin swa->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); 1378c0341432SJohn Baldwin if (swa->sw_ictx == NULL) 1379c0341432SJohn Baldwin return (ENOBUFS); 1380c0341432SJohn Baldwin axf->Init(swa->sw_ictx); 1381c0341432SJohn Baldwin if (csp->csp_cipher_key != NULL) 1382c0341432SJohn Baldwin axf->Setkey(swa->sw_ictx, csp->csp_cipher_key, 1383c0341432SJohn Baldwin csp->csp_cipher_klen); 138408fca7a5SJohn-Mark Gurney 1385c0341432SJohn Baldwin /* Second, setup the cipher side. */ 13863e947048SJohn Baldwin return (swcr_setup_cipher(ses, csp)); 13872e2e26d1SJohn Baldwin } 1388a2bc81bfSJohn-Mark Gurney 1389dd2e1352SJohn Baldwin static int 1390dd2e1352SJohn Baldwin swcr_setup_chacha20_poly1305(struct swcr_session *ses, 1391dd2e1352SJohn Baldwin const struct crypto_session_params *csp) 1392dd2e1352SJohn Baldwin { 1393dd2e1352SJohn Baldwin struct swcr_auth *swa; 1394d8787d4fSMark Johnston const struct auth_hash *axf; 1395dd2e1352SJohn Baldwin 1396dd2e1352SJohn Baldwin if (csp->csp_ivlen != CHACHA20_POLY1305_IV_LEN) 1397dd2e1352SJohn Baldwin return (EINVAL); 1398dd2e1352SJohn Baldwin 1399dd2e1352SJohn Baldwin /* First, setup the auth side. */ 1400dd2e1352SJohn Baldwin swa = &ses->swcr_auth; 1401dd2e1352SJohn Baldwin axf = &auth_hash_chacha20_poly1305; 1402dd2e1352SJohn Baldwin swa->sw_axf = axf; 1403dd2e1352SJohn Baldwin if (csp->csp_auth_mlen < 0 || csp->csp_auth_mlen > axf->hashsize) 1404dd2e1352SJohn Baldwin return (EINVAL); 1405dd2e1352SJohn Baldwin if (csp->csp_auth_mlen == 0) 1406dd2e1352SJohn Baldwin swa->sw_mlen = axf->hashsize; 1407dd2e1352SJohn Baldwin else 1408dd2e1352SJohn Baldwin swa->sw_mlen = csp->csp_auth_mlen; 1409dd2e1352SJohn Baldwin 1410dd2e1352SJohn Baldwin /* The auth state is regenerated for each nonce. */ 1411dd2e1352SJohn Baldwin 1412dd2e1352SJohn Baldwin /* Second, setup the cipher side. */ 1413dd2e1352SJohn Baldwin return (swcr_setup_cipher(ses, csp)); 1414dd2e1352SJohn Baldwin } 1415dd2e1352SJohn Baldwin 1416c0341432SJohn Baldwin static bool 1417c0341432SJohn Baldwin swcr_auth_supported(const struct crypto_session_params *csp) 1418109919c6SBenno Rice { 1419d8787d4fSMark Johnston const struct auth_hash *axf; 1420091d81d1SSam Leffler 1421c0341432SJohn Baldwin axf = crypto_auth_hash(csp); 1422c0341432SJohn Baldwin if (axf == NULL) 1423c0341432SJohn Baldwin return (false); 1424c0341432SJohn Baldwin switch (csp->csp_auth_alg) { 1425091d81d1SSam Leffler case CRYPTO_SHA1_HMAC: 1426c97f39ceSConrad Meyer case CRYPTO_SHA2_224_HMAC: 1427f6c4bc3bSPawel Jakub Dawidek case CRYPTO_SHA2_256_HMAC: 1428f6c4bc3bSPawel Jakub Dawidek case CRYPTO_SHA2_384_HMAC: 1429f6c4bc3bSPawel Jakub Dawidek case CRYPTO_SHA2_512_HMAC: 1430091d81d1SSam Leffler case CRYPTO_NULL_HMAC: 1431c0341432SJohn Baldwin case CRYPTO_RIPEMD160_HMAC: 1432091d81d1SSam Leffler break; 1433c0341432SJohn Baldwin case CRYPTO_AES_NIST_GMAC: 1434c0341432SJohn Baldwin switch (csp->csp_auth_klen * 8) { 1435c0341432SJohn Baldwin case 128: 1436c0341432SJohn Baldwin case 192: 1437c0341432SJohn Baldwin case 256: 1438c0341432SJohn Baldwin break; 1439c0341432SJohn Baldwin default: 1440c0341432SJohn Baldwin return (false); 1441c0341432SJohn Baldwin } 1442c0341432SJohn Baldwin if (csp->csp_auth_key == NULL) 1443c0341432SJohn Baldwin return (false); 1444c0341432SJohn Baldwin if (csp->csp_ivlen != AES_GCM_IV_LEN) 1445c0341432SJohn Baldwin return (false); 1446c0341432SJohn Baldwin break; 144725b7033bSConrad Meyer case CRYPTO_POLY1305: 1448c0341432SJohn Baldwin if (csp->csp_auth_klen != POLY1305_KEY_LEN) 1449c0341432SJohn Baldwin return (false); 1450c0341432SJohn Baldwin break; 1451c0341432SJohn Baldwin case CRYPTO_AES_CCM_CBC_MAC: 1452c0341432SJohn Baldwin switch (csp->csp_auth_klen * 8) { 1453c0341432SJohn Baldwin case 128: 1454c0341432SJohn Baldwin case 192: 1455c0341432SJohn Baldwin case 256: 1456c0341432SJohn Baldwin break; 1457c0341432SJohn Baldwin default: 1458c0341432SJohn Baldwin return (false); 1459c0341432SJohn Baldwin } 1460c0341432SJohn Baldwin if (csp->csp_auth_key == NULL) 1461c0341432SJohn Baldwin return (false); 1462c0341432SJohn Baldwin break; 1463c0341432SJohn Baldwin } 1464c0341432SJohn Baldwin return (true); 1465c0341432SJohn Baldwin } 1466091d81d1SSam Leffler 1467c0341432SJohn Baldwin static bool 1468c0341432SJohn Baldwin swcr_cipher_supported(const struct crypto_session_params *csp) 1469c0341432SJohn Baldwin { 1470d8787d4fSMark Johnston const struct enc_xform *txf; 1471c0341432SJohn Baldwin 1472c0341432SJohn Baldwin txf = crypto_cipher(csp); 1473c0341432SJohn Baldwin if (txf == NULL) 1474c0341432SJohn Baldwin return (false); 1475c0341432SJohn Baldwin if (csp->csp_cipher_alg != CRYPTO_NULL_CBC && 1476c0341432SJohn Baldwin txf->ivsize != csp->csp_ivlen) 1477c0341432SJohn Baldwin return (false); 1478c0341432SJohn Baldwin return (true); 1479c0341432SJohn Baldwin } 1480c0341432SJohn Baldwin 14816038018aSMarcin Wojtas #define SUPPORTED_SES (CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD | CSP_F_ESN) 14826038018aSMarcin Wojtas 1483c0341432SJohn Baldwin static int 1484c0341432SJohn Baldwin swcr_probesession(device_t dev, const struct crypto_session_params *csp) 1485c0341432SJohn Baldwin { 14866038018aSMarcin Wojtas if ((csp->csp_flags & ~(SUPPORTED_SES)) != 0) 1487c0341432SJohn Baldwin return (EINVAL); 1488c0341432SJohn Baldwin switch (csp->csp_mode) { 1489c0341432SJohn Baldwin case CSP_MODE_COMPRESS: 1490c0341432SJohn Baldwin switch (csp->csp_cipher_alg) { 1491c0341432SJohn Baldwin case CRYPTO_DEFLATE_COMP: 1492c0341432SJohn Baldwin break; 1493c0341432SJohn Baldwin default: 1494c0341432SJohn Baldwin return (EINVAL); 14955fbc5b5aSConrad Meyer } 1496091d81d1SSam Leffler break; 1497c0341432SJohn Baldwin case CSP_MODE_CIPHER: 1498c0341432SJohn Baldwin switch (csp->csp_cipher_alg) { 1499c0341432SJohn Baldwin case CRYPTO_AES_NIST_GCM_16: 1500c0341432SJohn Baldwin case CRYPTO_AES_CCM_16: 1501dd2e1352SJohn Baldwin case CRYPTO_CHACHA20_POLY1305: 1502c0341432SJohn Baldwin return (EINVAL); 1503c0341432SJohn Baldwin default: 1504c0341432SJohn Baldwin if (!swcr_cipher_supported(csp)) 1505c0341432SJohn Baldwin return (EINVAL); 1506091d81d1SSam Leffler break; 1507091d81d1SSam Leffler } 1508c0341432SJohn Baldwin break; 1509c0341432SJohn Baldwin case CSP_MODE_DIGEST: 1510c0341432SJohn Baldwin if (!swcr_auth_supported(csp)) 1511c0341432SJohn Baldwin return (EINVAL); 1512c0341432SJohn Baldwin break; 1513c0341432SJohn Baldwin case CSP_MODE_AEAD: 1514c0341432SJohn Baldwin switch (csp->csp_cipher_alg) { 1515c0341432SJohn Baldwin case CRYPTO_AES_NIST_GCM_16: 1516c0341432SJohn Baldwin case CRYPTO_AES_CCM_16: 1517dd2e1352SJohn Baldwin case CRYPTO_CHACHA20_POLY1305: 1518c0341432SJohn Baldwin break; 1519c0341432SJohn Baldwin default: 1520c0341432SJohn Baldwin return (EINVAL); 1521c0341432SJohn Baldwin } 1522c0341432SJohn Baldwin break; 1523c0341432SJohn Baldwin case CSP_MODE_ETA: 1524c0341432SJohn Baldwin /* AEAD algorithms cannot be used for EtA. */ 1525c0341432SJohn Baldwin switch (csp->csp_cipher_alg) { 1526c0341432SJohn Baldwin case CRYPTO_AES_NIST_GCM_16: 1527c0341432SJohn Baldwin case CRYPTO_AES_CCM_16: 1528dd2e1352SJohn Baldwin case CRYPTO_CHACHA20_POLY1305: 1529c0341432SJohn Baldwin return (EINVAL); 1530c0341432SJohn Baldwin } 1531c0341432SJohn Baldwin switch (csp->csp_auth_alg) { 1532c0341432SJohn Baldwin case CRYPTO_AES_NIST_GMAC: 1533c0341432SJohn Baldwin case CRYPTO_AES_CCM_CBC_MAC: 1534c0341432SJohn Baldwin return (EINVAL); 1535c0341432SJohn Baldwin } 1536c0341432SJohn Baldwin 1537c0341432SJohn Baldwin if (!swcr_cipher_supported(csp) || 1538c0341432SJohn Baldwin !swcr_auth_supported(csp)) 1539c0341432SJohn Baldwin return (EINVAL); 1540c0341432SJohn Baldwin break; 1541c0341432SJohn Baldwin default: 1542c0341432SJohn Baldwin return (EINVAL); 1543c0341432SJohn Baldwin } 1544c0341432SJohn Baldwin 1545c0341432SJohn Baldwin return (CRYPTODEV_PROBE_SOFTWARE); 1546c0341432SJohn Baldwin } 1547c0341432SJohn Baldwin 1548c0341432SJohn Baldwin /* 1549c0341432SJohn Baldwin * Generate a new software session. 1550c0341432SJohn Baldwin */ 1551c0341432SJohn Baldwin static int 1552c0341432SJohn Baldwin swcr_newsession(device_t dev, crypto_session_t cses, 1553c0341432SJohn Baldwin const struct crypto_session_params *csp) 1554c0341432SJohn Baldwin { 1555c0341432SJohn Baldwin struct swcr_session *ses; 1556c0341432SJohn Baldwin struct swcr_encdec *swe; 1557c0341432SJohn Baldwin struct swcr_auth *swa; 1558d8787d4fSMark Johnston const struct comp_algo *cxf; 1559c0341432SJohn Baldwin int error; 1560c0341432SJohn Baldwin 1561c0341432SJohn Baldwin ses = crypto_get_driver_session(cses); 1562c0341432SJohn Baldwin mtx_init(&ses->swcr_lock, "swcr session lock", NULL, MTX_DEF); 1563c0341432SJohn Baldwin 1564c0341432SJohn Baldwin error = 0; 1565c0341432SJohn Baldwin swe = &ses->swcr_encdec; 1566c0341432SJohn Baldwin swa = &ses->swcr_auth; 1567c0341432SJohn Baldwin switch (csp->csp_mode) { 1568c0341432SJohn Baldwin case CSP_MODE_COMPRESS: 1569c0341432SJohn Baldwin switch (csp->csp_cipher_alg) { 1570c0341432SJohn Baldwin case CRYPTO_DEFLATE_COMP: 1571c0341432SJohn Baldwin cxf = &comp_algo_deflate; 1572c0341432SJohn Baldwin break; 1573c0341432SJohn Baldwin #ifdef INVARIANTS 1574c0341432SJohn Baldwin default: 1575c0341432SJohn Baldwin panic("bad compression algo"); 1576c0341432SJohn Baldwin #endif 1577c0341432SJohn Baldwin } 1578c0341432SJohn Baldwin ses->swcr_compdec.sw_cxf = cxf; 1579c0341432SJohn Baldwin ses->swcr_process = swcr_compdec; 1580c0341432SJohn Baldwin break; 1581c0341432SJohn Baldwin case CSP_MODE_CIPHER: 1582c0341432SJohn Baldwin switch (csp->csp_cipher_alg) { 1583c0341432SJohn Baldwin case CRYPTO_NULL_CBC: 1584c0341432SJohn Baldwin ses->swcr_process = swcr_null; 1585c0341432SJohn Baldwin break; 1586c0341432SJohn Baldwin #ifdef INVARIANTS 1587c0341432SJohn Baldwin case CRYPTO_AES_NIST_GCM_16: 1588c0341432SJohn Baldwin case CRYPTO_AES_CCM_16: 1589dd2e1352SJohn Baldwin case CRYPTO_CHACHA20_POLY1305: 1590c0341432SJohn Baldwin panic("bad cipher algo"); 1591c0341432SJohn Baldwin #endif 1592c0341432SJohn Baldwin default: 15933e947048SJohn Baldwin error = swcr_setup_cipher(ses, csp); 1594c0341432SJohn Baldwin if (error == 0) 1595c0341432SJohn Baldwin ses->swcr_process = swcr_encdec; 1596c0341432SJohn Baldwin } 1597c0341432SJohn Baldwin break; 1598c0341432SJohn Baldwin case CSP_MODE_DIGEST: 1599c0341432SJohn Baldwin error = swcr_setup_auth(ses, csp); 1600c0341432SJohn Baldwin break; 1601c0341432SJohn Baldwin case CSP_MODE_AEAD: 1602c0341432SJohn Baldwin switch (csp->csp_cipher_alg) { 1603c0341432SJohn Baldwin case CRYPTO_AES_NIST_GCM_16: 1604c0341432SJohn Baldwin error = swcr_setup_gcm(ses, csp); 1605c0341432SJohn Baldwin if (error == 0) 1606c0341432SJohn Baldwin ses->swcr_process = swcr_gcm; 1607c0341432SJohn Baldwin break; 1608c0341432SJohn Baldwin case CRYPTO_AES_CCM_16: 1609c0341432SJohn Baldwin error = swcr_setup_ccm(ses, csp); 1610c0341432SJohn Baldwin if (error == 0) 1611c0341432SJohn Baldwin ses->swcr_process = swcr_ccm; 1612c0341432SJohn Baldwin break; 1613dd2e1352SJohn Baldwin case CRYPTO_CHACHA20_POLY1305: 1614dd2e1352SJohn Baldwin error = swcr_setup_chacha20_poly1305(ses, csp); 1615dd2e1352SJohn Baldwin if (error == 0) 1616dd2e1352SJohn Baldwin ses->swcr_process = swcr_chacha20_poly1305; 1617dd2e1352SJohn Baldwin break; 1618c0341432SJohn Baldwin #ifdef INVARIANTS 1619c0341432SJohn Baldwin default: 1620c0341432SJohn Baldwin panic("bad aead algo"); 1621c0341432SJohn Baldwin #endif 1622c0341432SJohn Baldwin } 1623c0341432SJohn Baldwin break; 1624c0341432SJohn Baldwin case CSP_MODE_ETA: 1625c0341432SJohn Baldwin #ifdef INVARIANTS 1626c0341432SJohn Baldwin switch (csp->csp_cipher_alg) { 1627c0341432SJohn Baldwin case CRYPTO_AES_NIST_GCM_16: 1628c0341432SJohn Baldwin case CRYPTO_AES_CCM_16: 1629dd2e1352SJohn Baldwin case CRYPTO_CHACHA20_POLY1305: 1630c0341432SJohn Baldwin panic("bad eta cipher algo"); 1631c0341432SJohn Baldwin } 1632c0341432SJohn Baldwin switch (csp->csp_auth_alg) { 1633c0341432SJohn Baldwin case CRYPTO_AES_NIST_GMAC: 1634c0341432SJohn Baldwin case CRYPTO_AES_CCM_CBC_MAC: 1635c0341432SJohn Baldwin panic("bad eta auth algo"); 1636c0341432SJohn Baldwin } 1637c0341432SJohn Baldwin #endif 1638c0341432SJohn Baldwin 1639c0341432SJohn Baldwin error = swcr_setup_auth(ses, csp); 1640c0341432SJohn Baldwin if (error) 1641c0341432SJohn Baldwin break; 1642c0341432SJohn Baldwin if (csp->csp_cipher_alg == CRYPTO_NULL_CBC) { 1643c0341432SJohn Baldwin /* Effectively degrade to digest mode. */ 1644c0341432SJohn Baldwin ses->swcr_process = swcr_authcompute; 1645c0341432SJohn Baldwin break; 1646c0341432SJohn Baldwin } 1647c0341432SJohn Baldwin 16483e947048SJohn Baldwin error = swcr_setup_cipher(ses, csp); 1649c0341432SJohn Baldwin if (error == 0) 1650c0341432SJohn Baldwin ses->swcr_process = swcr_eta; 1651c0341432SJohn Baldwin break; 1652c0341432SJohn Baldwin default: 1653c0341432SJohn Baldwin error = EINVAL; 1654c0341432SJohn Baldwin } 1655c0341432SJohn Baldwin 1656c0341432SJohn Baldwin if (error) 1657c0341432SJohn Baldwin swcr_freesession(dev, cses); 1658c0341432SJohn Baldwin return (error); 1659c0341432SJohn Baldwin } 1660c0341432SJohn Baldwin 1661c0341432SJohn Baldwin static void 1662c0341432SJohn Baldwin swcr_freesession(device_t dev, crypto_session_t cses) 1663c0341432SJohn Baldwin { 1664c0341432SJohn Baldwin struct swcr_session *ses; 1665c0341432SJohn Baldwin 1666c0341432SJohn Baldwin ses = crypto_get_driver_session(cses); 1667c0341432SJohn Baldwin 1668c0341432SJohn Baldwin mtx_destroy(&ses->swcr_lock); 1669c0341432SJohn Baldwin 16703e947048SJohn Baldwin zfree(ses->swcr_encdec.sw_kschedule, M_CRYPTO_DATA); 16714a711b8dSJohn Baldwin zfree(ses->swcr_auth.sw_ictx, M_CRYPTO_DATA); 16724a711b8dSJohn Baldwin zfree(ses->swcr_auth.sw_octx, M_CRYPTO_DATA); 1673091d81d1SSam Leffler } 1674091d81d1SSam Leffler 1675091d81d1SSam Leffler /* 1676091d81d1SSam Leffler * Process a software request. 1677091d81d1SSam Leffler */ 1678091d81d1SSam Leffler static int 16796810ad6fSSam Leffler swcr_process(device_t dev, struct cryptop *crp, int hint) 1680091d81d1SSam Leffler { 1681c0341432SJohn Baldwin struct swcr_session *ses; 1682091d81d1SSam Leffler 16831b0909d5SConrad Meyer ses = crypto_get_driver_session(crp->crp_session); 1684a7fcb1afSSean Eric Fagan mtx_lock(&ses->swcr_lock); 1685091d81d1SSam Leffler 1686c0341432SJohn Baldwin crp->crp_etype = ses->swcr_process(ses, crp); 1687091d81d1SSam Leffler 1688a7fcb1afSSean Eric Fagan mtx_unlock(&ses->swcr_lock); 1689091d81d1SSam Leffler crypto_done(crp); 1690c0341432SJohn Baldwin return (0); 1691091d81d1SSam Leffler } 1692091d81d1SSam Leffler 1693091d81d1SSam Leffler static void 16943f147ab2SWarner Losh swcr_identify(driver_t *drv, device_t parent) 1695091d81d1SSam Leffler { 16966810ad6fSSam Leffler /* NB: order 10 is so we get attached after h/w devices */ 16976810ad6fSSam Leffler if (device_find_child(parent, "cryptosoft", -1) == NULL && 169886c585d9SMarius Strobl BUS_ADD_CHILD(parent, 10, "cryptosoft", 0) == 0) 16996810ad6fSSam Leffler panic("cryptosoft: could not attach"); 17006810ad6fSSam Leffler } 1701f6c4bc3bSPawel Jakub Dawidek 17026810ad6fSSam Leffler static int 17036810ad6fSSam Leffler swcr_probe(device_t dev) 17046810ad6fSSam Leffler { 17056810ad6fSSam Leffler device_set_desc(dev, "software crypto"); 17064fc60fa9SMark Johnston device_quiet(dev); 170786c585d9SMarius Strobl return (BUS_PROBE_NOWILDCARD); 17086810ad6fSSam Leffler } 1709f6c4bc3bSPawel Jakub Dawidek 17106810ad6fSSam Leffler static int 17116810ad6fSSam Leffler swcr_attach(device_t dev) 17126810ad6fSSam Leffler { 17136810ad6fSSam Leffler 17149ebbebe4SConrad Meyer swcr_id = crypto_get_driverid(dev, sizeof(struct swcr_session), 17156810ad6fSSam Leffler CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC); 17166810ad6fSSam Leffler if (swcr_id < 0) { 17176810ad6fSSam Leffler device_printf(dev, "cannot initialize!"); 1718c0341432SJohn Baldwin return (ENXIO); 17196810ad6fSSam Leffler } 17206810ad6fSSam Leffler 1721c0341432SJohn Baldwin return (0); 1722091d81d1SSam Leffler } 17234b465da2SPawel Jakub Dawidek 17243f147ab2SWarner Losh static int 17256810ad6fSSam Leffler swcr_detach(device_t dev) 17264b465da2SPawel Jakub Dawidek { 17276810ad6fSSam Leffler crypto_unregister_all(swcr_id); 17283f147ab2SWarner Losh return 0; 17294b465da2SPawel Jakub Dawidek } 17306810ad6fSSam Leffler 17316810ad6fSSam Leffler static device_method_t swcr_methods[] = { 17326810ad6fSSam Leffler DEVMETHOD(device_identify, swcr_identify), 17336810ad6fSSam Leffler DEVMETHOD(device_probe, swcr_probe), 17346810ad6fSSam Leffler DEVMETHOD(device_attach, swcr_attach), 17356810ad6fSSam Leffler DEVMETHOD(device_detach, swcr_detach), 17366810ad6fSSam Leffler 1737c0341432SJohn Baldwin DEVMETHOD(cryptodev_probesession, swcr_probesession), 17386810ad6fSSam Leffler DEVMETHOD(cryptodev_newsession, swcr_newsession), 17396810ad6fSSam Leffler DEVMETHOD(cryptodev_freesession,swcr_freesession), 17406810ad6fSSam Leffler DEVMETHOD(cryptodev_process, swcr_process), 17416810ad6fSSam Leffler 17426810ad6fSSam Leffler {0, 0}, 17436810ad6fSSam Leffler }; 17446810ad6fSSam Leffler 17456810ad6fSSam Leffler static driver_t swcr_driver = { 17466810ad6fSSam Leffler "cryptosoft", 17476810ad6fSSam Leffler swcr_methods, 17486810ad6fSSam Leffler 0, /* NB: no softc */ 17496810ad6fSSam Leffler }; 17506810ad6fSSam Leffler static devclass_t swcr_devclass; 17516810ad6fSSam Leffler 17526810ad6fSSam Leffler /* 17536810ad6fSSam Leffler * NB: We explicitly reference the crypto module so we 17546810ad6fSSam Leffler * get the necessary ordering when built as a loadable 17556810ad6fSSam Leffler * module. This is required because we bundle the crypto 17566810ad6fSSam Leffler * module code together with the cryptosoft driver (otherwise 17576810ad6fSSam Leffler * normal module dependencies would handle things). 17586810ad6fSSam Leffler */ 17596810ad6fSSam Leffler extern int crypto_modevent(struct module *, int, void *); 17606810ad6fSSam Leffler /* XXX where to attach */ 17616810ad6fSSam Leffler DRIVER_MODULE(cryptosoft, nexus, swcr_driver, swcr_devclass, crypto_modevent,0); 17626810ad6fSSam Leffler MODULE_VERSION(cryptosoft, 1); 17636810ad6fSSam Leffler MODULE_DEPEND(cryptosoft, crypto, 1, 1, 1); 1764