1104476Ssam/* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */ 2139825Simp/*- 3104476Ssam * The authors of this code are John Ioannidis (ji@tla.org), 4247061Spjd * Angelos D. Keromytis (kermit@csd.uch.gr), 5247061Spjd * Niels Provos (provos@physnet.uni-hamburg.de) and 6247061Spjd * Damien Miller (djm@mindrot.org). 7104476Ssam * 8104476Ssam * This code was written by John Ioannidis for BSD/OS in Athens, Greece, 9104476Ssam * in November 1995. 10104476Ssam * 11104476Ssam * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, 12104476Ssam * by Angelos D. Keromytis. 13104476Ssam * 14104476Ssam * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis 15104476Ssam * and Niels Provos. 16104476Ssam * 17104476Ssam * Additional features in 1999 by Angelos D. Keromytis. 18104476Ssam * 19247061Spjd * AES XTS implementation in 2008 by Damien Miller 20247061Spjd * 21104476Ssam * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis, 22104476Ssam * Angelos D. Keromytis and Niels Provos. 23104476Ssam * 24104476Ssam * Copyright (C) 2001, Angelos D. Keromytis. 25104476Ssam * 26247061Spjd * Copyright (C) 2008, Damien Miller 27247061Spjd * 28104476Ssam * Permission to use, copy, and modify this software with or without fee 29104476Ssam * is hereby granted, provided that this entire notice is included in 30104476Ssam * all copies of any software which is or includes a copy or 31104476Ssam * modification of this software. 32104476Ssam * You may use this code under the GNU public license if you so wish. Please 33104476Ssam * contribute changes back to the authors under this freer than GPL license 34104476Ssam * so that we may further the use of strong encryption without limitations to 35104476Ssam * all. 36104476Ssam * 37104476Ssam * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 38104476Ssam * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY 39104476Ssam * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 40104476Ssam * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 41104476Ssam * PURPOSE. 42104476Ssam */ 43104476Ssam 44116191Sobrien#include <sys/cdefs.h> 45116191Sobrien__FBSDID("$FreeBSD$"); 46116191Sobrien 47104476Ssam#include <sys/param.h> 48104476Ssam#include <sys/systm.h> 49104476Ssam#include <sys/malloc.h> 50104476Ssam#include <sys/sysctl.h> 51104476Ssam#include <sys/errno.h> 52104476Ssam#include <sys/time.h> 53104476Ssam#include <sys/kernel.h> 54104476Ssam#include <machine/cpu.h> 55104476Ssam 56104476Ssam#include <crypto/blowfish/blowfish.h> 57104476Ssam#include <crypto/des/des.h> 58143423Sume#include <crypto/rijndael/rijndael.h> 59169425Sgnn#include <crypto/camellia/camellia.h> 60104476Ssam#include <crypto/sha1.h> 61104476Ssam 62104476Ssam#include <opencrypto/cast.h> 63104476Ssam#include <opencrypto/deflate.h> 64104476Ssam#include <opencrypto/rmd160.h> 65104476Ssam#include <opencrypto/skipjack.h> 66104476Ssam 67104476Ssam#include <sys/md5.h> 68104476Ssam 69104476Ssam#include <opencrypto/cryptodev.h> 70104476Ssam#include <opencrypto/xform.h> 71104476Ssam 72213068Spjdstatic int null_setkey(u_int8_t **, u_int8_t *, int); 73104476Ssamstatic int des1_setkey(u_int8_t **, u_int8_t *, int); 74104476Ssamstatic int des3_setkey(u_int8_t **, u_int8_t *, int); 75104476Ssamstatic int blf_setkey(u_int8_t **, u_int8_t *, int); 76104476Ssamstatic int cast5_setkey(u_int8_t **, u_int8_t *, int); 77104476Ssamstatic int skipjack_setkey(u_int8_t **, u_int8_t *, int); 78104476Ssamstatic int rijndael128_setkey(u_int8_t **, u_int8_t *, int); 79213068Spjdstatic int aes_xts_setkey(u_int8_t **, u_int8_t *, int); 80169425Sgnnstatic int cml_setkey(u_int8_t **, u_int8_t *, int); 81213068Spjd 82213068Spjdstatic void null_encrypt(caddr_t, u_int8_t *); 83104476Ssamstatic void des1_encrypt(caddr_t, u_int8_t *); 84104476Ssamstatic void des3_encrypt(caddr_t, u_int8_t *); 85104476Ssamstatic void blf_encrypt(caddr_t, u_int8_t *); 86104476Ssamstatic void cast5_encrypt(caddr_t, u_int8_t *); 87104476Ssamstatic void skipjack_encrypt(caddr_t, u_int8_t *); 88104476Ssamstatic void rijndael128_encrypt(caddr_t, u_int8_t *); 89213068Spjdstatic void aes_xts_encrypt(caddr_t, u_int8_t *); 90169425Sgnnstatic void cml_encrypt(caddr_t, u_int8_t *); 91213068Spjd 92213068Spjdstatic void null_decrypt(caddr_t, u_int8_t *); 93104476Ssamstatic void des1_decrypt(caddr_t, u_int8_t *); 94104476Ssamstatic void des3_decrypt(caddr_t, u_int8_t *); 95104476Ssamstatic void blf_decrypt(caddr_t, u_int8_t *); 96104476Ssamstatic void cast5_decrypt(caddr_t, u_int8_t *); 97104476Ssamstatic void skipjack_decrypt(caddr_t, u_int8_t *); 98104476Ssamstatic void rijndael128_decrypt(caddr_t, u_int8_t *); 99213068Spjdstatic void aes_xts_decrypt(caddr_t, u_int8_t *); 100169425Sgnnstatic void cml_decrypt(caddr_t, u_int8_t *); 101213068Spjd 102213068Spjdstatic void null_zerokey(u_int8_t **); 103104476Ssamstatic void des1_zerokey(u_int8_t **); 104104476Ssamstatic void des3_zerokey(u_int8_t **); 105104476Ssamstatic void blf_zerokey(u_int8_t **); 106104476Ssamstatic void cast5_zerokey(u_int8_t **); 107104476Ssamstatic void skipjack_zerokey(u_int8_t **); 108104476Ssamstatic void rijndael128_zerokey(u_int8_t **); 109213068Spjdstatic void aes_xts_zerokey(u_int8_t **); 110169425Sgnnstatic void cml_zerokey(u_int8_t **); 111104476Ssam 112213068Spjdstatic void aes_xts_reinit(caddr_t, u_int8_t *); 113213068Spjd 114104476Ssamstatic void null_init(void *); 115104476Ssamstatic int null_update(void *, u_int8_t *, u_int16_t); 116104476Ssamstatic void null_final(u_int8_t *, void *); 117104476Ssamstatic int MD5Update_int(void *, u_int8_t *, u_int16_t); 118104476Ssamstatic void SHA1Init_int(void *); 119104476Ssamstatic int SHA1Update_int(void *, u_int8_t *, u_int16_t); 120104476Ssamstatic void SHA1Final_int(u_int8_t *, void *); 121104476Ssamstatic int RMD160Update_int(void *, u_int8_t *, u_int16_t); 122104476Ssamstatic int SHA256Update_int(void *, u_int8_t *, u_int16_t); 123104476Ssamstatic int SHA384Update_int(void *, u_int8_t *, u_int16_t); 124104476Ssamstatic int SHA512Update_int(void *, u_int8_t *, u_int16_t); 125104476Ssam 126104476Ssamstatic u_int32_t deflate_compress(u_int8_t *, u_int32_t, u_int8_t **); 127104476Ssamstatic u_int32_t deflate_decompress(u_int8_t *, u_int32_t, u_int8_t **); 128104476Ssam 129104476SsamMALLOC_DEFINE(M_XDATA, "xform", "xform data buffers"); 130104476Ssam 131104476Ssam/* Encryption instances */ 132104476Ssamstruct enc_xform enc_xform_null = { 133104476Ssam CRYPTO_NULL_CBC, "NULL", 134104476Ssam /* NB: blocksize of 4 is to generate a properly aligned ESP header */ 135159235Spjd NULL_BLOCK_LEN, 0, 256, /* 2048 bits, max key */ 136104476Ssam null_encrypt, 137104476Ssam null_decrypt, 138104476Ssam null_setkey, 139104476Ssam null_zerokey, 140213068Spjd NULL 141104476Ssam}; 142104476Ssam 143104476Ssamstruct enc_xform enc_xform_des = { 144104476Ssam CRYPTO_DES_CBC, "DES", 145159235Spjd DES_BLOCK_LEN, 8, 8, 146104476Ssam des1_encrypt, 147104476Ssam des1_decrypt, 148104476Ssam des1_setkey, 149104476Ssam des1_zerokey, 150213068Spjd NULL 151104476Ssam}; 152104476Ssam 153104476Ssamstruct enc_xform enc_xform_3des = { 154104476Ssam CRYPTO_3DES_CBC, "3DES", 155159235Spjd DES3_BLOCK_LEN, 24, 24, 156104476Ssam des3_encrypt, 157104476Ssam des3_decrypt, 158104476Ssam des3_setkey, 159213068Spjd des3_zerokey, 160213068Spjd NULL 161104476Ssam}; 162104476Ssam 163104476Ssamstruct enc_xform enc_xform_blf = { 164104476Ssam CRYPTO_BLF_CBC, "Blowfish", 165159235Spjd BLOWFISH_BLOCK_LEN, 5, 56 /* 448 bits, max key */, 166104476Ssam blf_encrypt, 167104476Ssam blf_decrypt, 168104476Ssam blf_setkey, 169213068Spjd blf_zerokey, 170213068Spjd NULL 171104476Ssam}; 172104476Ssam 173104476Ssamstruct enc_xform enc_xform_cast5 = { 174104476Ssam CRYPTO_CAST_CBC, "CAST-128", 175159235Spjd CAST128_BLOCK_LEN, 5, 16, 176104476Ssam cast5_encrypt, 177104476Ssam cast5_decrypt, 178104476Ssam cast5_setkey, 179213068Spjd cast5_zerokey, 180213068Spjd NULL 181104476Ssam}; 182104476Ssam 183104476Ssamstruct enc_xform enc_xform_skipjack = { 184104476Ssam CRYPTO_SKIPJACK_CBC, "Skipjack", 185159235Spjd SKIPJACK_BLOCK_LEN, 10, 10, 186104476Ssam skipjack_encrypt, 187104476Ssam skipjack_decrypt, 188104476Ssam skipjack_setkey, 189213068Spjd skipjack_zerokey, 190213068Spjd NULL 191104476Ssam}; 192104476Ssam 193104476Ssamstruct enc_xform enc_xform_rijndael128 = { 194104476Ssam CRYPTO_RIJNDAEL128_CBC, "Rijndael-128/AES", 195159235Spjd RIJNDAEL128_BLOCK_LEN, 8, 32, 196104476Ssam rijndael128_encrypt, 197104476Ssam rijndael128_decrypt, 198104476Ssam rijndael128_setkey, 199104476Ssam rijndael128_zerokey, 200213068Spjd NULL 201104476Ssam}; 202104476Ssam 203213068Spjdstruct enc_xform enc_xform_aes_xts = { 204213068Spjd CRYPTO_AES_XTS, "AES-XTS", 205213068Spjd RIJNDAEL128_BLOCK_LEN, 32, 64, 206213068Spjd aes_xts_encrypt, 207213068Spjd aes_xts_decrypt, 208213068Spjd aes_xts_setkey, 209213068Spjd aes_xts_zerokey, 210213068Spjd aes_xts_reinit 211213068Spjd}; 212213068Spjd 213104476Ssamstruct enc_xform enc_xform_arc4 = { 214104476Ssam CRYPTO_ARC4, "ARC4", 215104476Ssam 1, 1, 32, 216104476Ssam NULL, 217104476Ssam NULL, 218104476Ssam NULL, 219104476Ssam NULL, 220213068Spjd NULL 221104476Ssam}; 222104476Ssam 223169425Sgnnstruct enc_xform enc_xform_camellia = { 224169425Sgnn CRYPTO_CAMELLIA_CBC, "Camellia", 225169425Sgnn CAMELLIA_BLOCK_LEN, 8, 32, 226169425Sgnn cml_encrypt, 227169425Sgnn cml_decrypt, 228169425Sgnn cml_setkey, 229169425Sgnn cml_zerokey, 230213068Spjd NULL 231169425Sgnn}; 232169425Sgnn 233104476Ssam/* Authentication instances */ 234104476Ssamstruct auth_hash auth_hash_null = { 235104476Ssam CRYPTO_NULL_HMAC, "NULL-HMAC", 236159235Spjd 0, NULL_HASH_LEN, NULL_HMAC_BLOCK_LEN, sizeof(int), /* NB: context isn't used */ 237104476Ssam null_init, null_update, null_final 238104476Ssam}; 239104476Ssam 240158703Spjdstruct auth_hash auth_hash_hmac_md5 = { 241104476Ssam CRYPTO_MD5_HMAC, "HMAC-MD5", 242159235Spjd 16, MD5_HASH_LEN, MD5_HMAC_BLOCK_LEN, sizeof(MD5_CTX), 243104476Ssam (void (*) (void *)) MD5Init, MD5Update_int, 244104476Ssam (void (*) (u_int8_t *, void *)) MD5Final 245104476Ssam}; 246104476Ssam 247158703Spjdstruct auth_hash auth_hash_hmac_sha1 = { 248104476Ssam CRYPTO_SHA1_HMAC, "HMAC-SHA1", 249159235Spjd 20, SHA1_HASH_LEN, SHA1_HMAC_BLOCK_LEN, sizeof(SHA1_CTX), 250104476Ssam SHA1Init_int, SHA1Update_int, SHA1Final_int 251104476Ssam}; 252104476Ssam 253158703Spjdstruct auth_hash auth_hash_hmac_ripemd_160 = { 254104476Ssam CRYPTO_RIPEMD160_HMAC, "HMAC-RIPEMD-160", 255159235Spjd 20, RIPEMD160_HASH_LEN, RIPEMD160_HMAC_BLOCK_LEN, sizeof(RMD160_CTX), 256104476Ssam (void (*)(void *)) RMD160Init, RMD160Update_int, 257104476Ssam (void (*)(u_int8_t *, void *)) RMD160Final 258104476Ssam}; 259104476Ssam 260104476Ssamstruct auth_hash auth_hash_key_md5 = { 261213065Spjd CRYPTO_MD5_KPDK, "Keyed MD5", 262159235Spjd 0, MD5_KPDK_HASH_LEN, 0, sizeof(MD5_CTX), 263104476Ssam (void (*)(void *)) MD5Init, MD5Update_int, 264104476Ssam (void (*)(u_int8_t *, void *)) MD5Final 265104476Ssam}; 266104476Ssam 267104476Ssamstruct auth_hash auth_hash_key_sha1 = { 268104476Ssam CRYPTO_SHA1_KPDK, "Keyed SHA1", 269159235Spjd 0, SHA1_KPDK_HASH_LEN, 0, sizeof(SHA1_CTX), 270104476Ssam SHA1Init_int, SHA1Update_int, SHA1Final_int 271104476Ssam}; 272104476Ssam 273104476Ssamstruct auth_hash auth_hash_hmac_sha2_256 = { 274158703Spjd CRYPTO_SHA2_256_HMAC, "HMAC-SHA2-256", 275159235Spjd 32, SHA2_256_HASH_LEN, SHA2_256_HMAC_BLOCK_LEN, sizeof(SHA256_CTX), 276104476Ssam (void (*)(void *)) SHA256_Init, SHA256Update_int, 277104476Ssam (void (*)(u_int8_t *, void *)) SHA256_Final 278104476Ssam}; 279104476Ssam 280104476Ssamstruct auth_hash auth_hash_hmac_sha2_384 = { 281158703Spjd CRYPTO_SHA2_384_HMAC, "HMAC-SHA2-384", 282159235Spjd 48, SHA2_384_HASH_LEN, SHA2_384_HMAC_BLOCK_LEN, sizeof(SHA384_CTX), 283104476Ssam (void (*)(void *)) SHA384_Init, SHA384Update_int, 284104476Ssam (void (*)(u_int8_t *, void *)) SHA384_Final 285104476Ssam}; 286104476Ssam 287104476Ssamstruct auth_hash auth_hash_hmac_sha2_512 = { 288158703Spjd CRYPTO_SHA2_512_HMAC, "HMAC-SHA2-512", 289159235Spjd 64, SHA2_512_HASH_LEN, SHA2_512_HMAC_BLOCK_LEN, sizeof(SHA512_CTX), 290104476Ssam (void (*)(void *)) SHA512_Init, SHA512Update_int, 291104476Ssam (void (*)(u_int8_t *, void *)) SHA512_Final 292104476Ssam}; 293104476Ssam 294104476Ssam/* Compression instance */ 295104476Ssamstruct comp_algo comp_algo_deflate = { 296104476Ssam CRYPTO_DEFLATE_COMP, "Deflate", 297104476Ssam 90, deflate_compress, 298104476Ssam deflate_decompress 299104476Ssam}; 300104476Ssam 301104476Ssam/* 302104476Ssam * Encryption wrapper routines. 303104476Ssam */ 304104476Ssamstatic void 305104476Ssamnull_encrypt(caddr_t key, u_int8_t *blk) 306104476Ssam{ 307104476Ssam} 308104476Ssamstatic void 309104476Ssamnull_decrypt(caddr_t key, u_int8_t *blk) 310104476Ssam{ 311104476Ssam} 312104476Ssamstatic int 313104476Ssamnull_setkey(u_int8_t **sched, u_int8_t *key, int len) 314104476Ssam{ 315104476Ssam *sched = NULL; 316104476Ssam return 0; 317104476Ssam} 318104476Ssamstatic void 319104476Ssamnull_zerokey(u_int8_t **sched) 320104476Ssam{ 321104476Ssam *sched = NULL; 322104476Ssam} 323104476Ssam 324104476Ssamstatic void 325104476Ssamdes1_encrypt(caddr_t key, u_int8_t *blk) 326104476Ssam{ 327104476Ssam des_cblock *cb = (des_cblock *) blk; 328104476Ssam des_key_schedule *p = (des_key_schedule *) key; 329104476Ssam 330104476Ssam des_ecb_encrypt(cb, cb, p[0], DES_ENCRYPT); 331104476Ssam} 332104476Ssam 333104476Ssamstatic void 334104476Ssamdes1_decrypt(caddr_t key, u_int8_t *blk) 335104476Ssam{ 336104476Ssam des_cblock *cb = (des_cblock *) blk; 337104476Ssam des_key_schedule *p = (des_key_schedule *) key; 338104476Ssam 339104476Ssam des_ecb_encrypt(cb, cb, p[0], DES_DECRYPT); 340104476Ssam} 341104476Ssam 342104476Ssamstatic int 343104476Ssamdes1_setkey(u_int8_t **sched, u_int8_t *key, int len) 344104476Ssam{ 345104476Ssam des_key_schedule *p; 346104476Ssam int err; 347104476Ssam 348184205Sdes p = malloc(sizeof (des_key_schedule), 349104476Ssam M_CRYPTO_DATA, M_NOWAIT|M_ZERO); 350104476Ssam if (p != NULL) { 351104476Ssam des_set_key((des_cblock *) key, p[0]); 352104476Ssam err = 0; 353104476Ssam } else 354104476Ssam err = ENOMEM; 355104476Ssam *sched = (u_int8_t *) p; 356104476Ssam return err; 357104476Ssam} 358104476Ssam 359104476Ssamstatic void 360104476Ssamdes1_zerokey(u_int8_t **sched) 361104476Ssam{ 362104476Ssam bzero(*sched, sizeof (des_key_schedule)); 363184205Sdes free(*sched, M_CRYPTO_DATA); 364104476Ssam *sched = NULL; 365104476Ssam} 366104476Ssam 367104476Ssamstatic void 368104476Ssamdes3_encrypt(caddr_t key, u_int8_t *blk) 369104476Ssam{ 370104476Ssam des_cblock *cb = (des_cblock *) blk; 371104476Ssam des_key_schedule *p = (des_key_schedule *) key; 372104476Ssam 373104476Ssam des_ecb3_encrypt(cb, cb, p[0], p[1], p[2], DES_ENCRYPT); 374104476Ssam} 375104476Ssam 376104476Ssamstatic void 377104476Ssamdes3_decrypt(caddr_t key, u_int8_t *blk) 378104476Ssam{ 379104476Ssam des_cblock *cb = (des_cblock *) blk; 380104476Ssam des_key_schedule *p = (des_key_schedule *) key; 381104476Ssam 382104476Ssam des_ecb3_encrypt(cb, cb, p[0], p[1], p[2], DES_DECRYPT); 383104476Ssam} 384104476Ssam 385104476Ssamstatic int 386104476Ssamdes3_setkey(u_int8_t **sched, u_int8_t *key, int len) 387104476Ssam{ 388104476Ssam des_key_schedule *p; 389104476Ssam int err; 390104476Ssam 391184205Sdes p = malloc(3*sizeof (des_key_schedule), 392104476Ssam M_CRYPTO_DATA, M_NOWAIT|M_ZERO); 393104476Ssam if (p != NULL) { 394104476Ssam des_set_key((des_cblock *)(key + 0), p[0]); 395104476Ssam des_set_key((des_cblock *)(key + 8), p[1]); 396104476Ssam des_set_key((des_cblock *)(key + 16), p[2]); 397104476Ssam err = 0; 398104476Ssam } else 399104476Ssam err = ENOMEM; 400104476Ssam *sched = (u_int8_t *) p; 401104476Ssam return err; 402104476Ssam} 403104476Ssam 404104476Ssamstatic void 405104476Ssamdes3_zerokey(u_int8_t **sched) 406104476Ssam{ 407104476Ssam bzero(*sched, 3*sizeof (des_key_schedule)); 408184205Sdes free(*sched, M_CRYPTO_DATA); 409104476Ssam *sched = NULL; 410104476Ssam} 411104476Ssam 412104476Ssamstatic void 413104476Ssamblf_encrypt(caddr_t key, u_int8_t *blk) 414104476Ssam{ 415104476Ssam BF_LONG t[2]; 416104476Ssam 417104476Ssam memcpy(t, blk, sizeof (t)); 418104476Ssam t[0] = ntohl(t[0]); 419104476Ssam t[1] = ntohl(t[1]); 420104476Ssam /* NB: BF_encrypt expects the block in host order! */ 421104476Ssam BF_encrypt(t, (BF_KEY *) key); 422104476Ssam t[0] = htonl(t[0]); 423104476Ssam t[1] = htonl(t[1]); 424104476Ssam memcpy(blk, t, sizeof (t)); 425104476Ssam} 426104476Ssam 427104476Ssamstatic void 428104476Ssamblf_decrypt(caddr_t key, u_int8_t *blk) 429104476Ssam{ 430104476Ssam BF_LONG t[2]; 431104476Ssam 432104476Ssam memcpy(t, blk, sizeof (t)); 433104476Ssam t[0] = ntohl(t[0]); 434104476Ssam t[1] = ntohl(t[1]); 435104476Ssam /* NB: BF_decrypt expects the block in host order! */ 436104476Ssam BF_decrypt(t, (BF_KEY *) key); 437104476Ssam t[0] = htonl(t[0]); 438104476Ssam t[1] = htonl(t[1]); 439104476Ssam memcpy(blk, t, sizeof (t)); 440104476Ssam} 441104476Ssam 442104476Ssamstatic int 443104476Ssamblf_setkey(u_int8_t **sched, u_int8_t *key, int len) 444104476Ssam{ 445104476Ssam int err; 446104476Ssam 447184205Sdes *sched = malloc(sizeof(BF_KEY), 448104476Ssam M_CRYPTO_DATA, M_NOWAIT|M_ZERO); 449104476Ssam if (*sched != NULL) { 450104476Ssam BF_set_key((BF_KEY *) *sched, len, key); 451104476Ssam err = 0; 452104476Ssam } else 453104476Ssam err = ENOMEM; 454104476Ssam return err; 455104476Ssam} 456104476Ssam 457104476Ssamstatic void 458104476Ssamblf_zerokey(u_int8_t **sched) 459104476Ssam{ 460104476Ssam bzero(*sched, sizeof(BF_KEY)); 461184205Sdes free(*sched, M_CRYPTO_DATA); 462104476Ssam *sched = NULL; 463104476Ssam} 464104476Ssam 465104476Ssamstatic void 466104476Ssamcast5_encrypt(caddr_t key, u_int8_t *blk) 467104476Ssam{ 468104476Ssam cast_encrypt((cast_key *) key, blk, blk); 469104476Ssam} 470104476Ssam 471104476Ssamstatic void 472104476Ssamcast5_decrypt(caddr_t key, u_int8_t *blk) 473104476Ssam{ 474104476Ssam cast_decrypt((cast_key *) key, blk, blk); 475104476Ssam} 476104476Ssam 477104476Ssamstatic int 478104476Ssamcast5_setkey(u_int8_t **sched, u_int8_t *key, int len) 479104476Ssam{ 480104476Ssam int err; 481104476Ssam 482184205Sdes *sched = malloc(sizeof(cast_key), M_CRYPTO_DATA, M_NOWAIT|M_ZERO); 483104476Ssam if (*sched != NULL) { 484104476Ssam cast_setkey((cast_key *)*sched, key, len); 485104476Ssam err = 0; 486104476Ssam } else 487104476Ssam err = ENOMEM; 488104476Ssam return err; 489104476Ssam} 490104476Ssam 491104476Ssamstatic void 492104476Ssamcast5_zerokey(u_int8_t **sched) 493104476Ssam{ 494104476Ssam bzero(*sched, sizeof(cast_key)); 495184205Sdes free(*sched, M_CRYPTO_DATA); 496104476Ssam *sched = NULL; 497104476Ssam} 498104476Ssam 499104476Ssamstatic void 500104476Ssamskipjack_encrypt(caddr_t key, u_int8_t *blk) 501104476Ssam{ 502104476Ssam skipjack_forwards(blk, blk, (u_int8_t **) key); 503104476Ssam} 504104476Ssam 505104476Ssamstatic void 506104476Ssamskipjack_decrypt(caddr_t key, u_int8_t *blk) 507104476Ssam{ 508104476Ssam skipjack_backwards(blk, blk, (u_int8_t **) key); 509104476Ssam} 510104476Ssam 511104476Ssamstatic int 512104476Ssamskipjack_setkey(u_int8_t **sched, u_int8_t *key, int len) 513104476Ssam{ 514104476Ssam int err; 515104476Ssam 516104476Ssam /* NB: allocate all the memory that's needed at once */ 517184205Sdes *sched = malloc(10 * (sizeof(u_int8_t *) + 0x100), 518104476Ssam M_CRYPTO_DATA, M_NOWAIT|M_ZERO); 519104476Ssam if (*sched != NULL) { 520104476Ssam u_int8_t** key_tables = (u_int8_t**) *sched; 521104476Ssam u_int8_t* table = (u_int8_t*) &key_tables[10]; 522104476Ssam int k; 523104476Ssam 524104476Ssam for (k = 0; k < 10; k++) { 525104476Ssam key_tables[k] = table; 526104476Ssam table += 0x100; 527104476Ssam } 528104476Ssam subkey_table_gen(key, (u_int8_t **) *sched); 529104476Ssam err = 0; 530104476Ssam } else 531104476Ssam err = ENOMEM; 532104476Ssam return err; 533104476Ssam} 534104476Ssam 535104476Ssamstatic void 536104476Ssamskipjack_zerokey(u_int8_t **sched) 537104476Ssam{ 538104476Ssam bzero(*sched, 10 * (sizeof(u_int8_t *) + 0x100)); 539184205Sdes free(*sched, M_CRYPTO_DATA); 540104476Ssam *sched = NULL; 541104476Ssam} 542104476Ssam 543104476Ssamstatic void 544104476Ssamrijndael128_encrypt(caddr_t key, u_int8_t *blk) 545104476Ssam{ 546104476Ssam rijndael_encrypt((rijndael_ctx *) key, (u_char *) blk, (u_char *) blk); 547104476Ssam} 548104476Ssam 549104476Ssamstatic void 550104476Ssamrijndael128_decrypt(caddr_t key, u_int8_t *blk) 551104476Ssam{ 552143408Sume rijndael_decrypt(((rijndael_ctx *) key), (u_char *) blk, 553104476Ssam (u_char *) blk); 554104476Ssam} 555104476Ssam 556104476Ssamstatic int 557104476Ssamrijndael128_setkey(u_int8_t **sched, u_int8_t *key, int len) 558104476Ssam{ 559104476Ssam int err; 560104476Ssam 561149143Spjd if (len != 16 && len != 24 && len != 32) 562149143Spjd return (EINVAL); 563184205Sdes *sched = malloc(sizeof(rijndael_ctx), M_CRYPTO_DATA, 564104476Ssam M_NOWAIT|M_ZERO); 565104476Ssam if (*sched != NULL) { 566143408Sume rijndael_set_key((rijndael_ctx *) *sched, (u_char *) key, 567143408Sume len * 8); 568104476Ssam err = 0; 569104476Ssam } else 570104476Ssam err = ENOMEM; 571104476Ssam return err; 572104476Ssam} 573104476Ssam 574104476Ssamstatic void 575104476Ssamrijndael128_zerokey(u_int8_t **sched) 576104476Ssam{ 577143408Sume bzero(*sched, sizeof(rijndael_ctx)); 578184205Sdes free(*sched, M_CRYPTO_DATA); 579104476Ssam *sched = NULL; 580104476Ssam} 581104476Ssam 582213068Spjd#define AES_XTS_BLOCKSIZE 16 583213068Spjd#define AES_XTS_IVSIZE 8 584213068Spjd#define AES_XTS_ALPHA 0x87 /* GF(2^128) generator polynomial */ 585213068Spjd 586213068Spjdstruct aes_xts_ctx { 587213068Spjd rijndael_ctx key1; 588213068Spjd rijndael_ctx key2; 589213068Spjd u_int8_t tweak[AES_XTS_BLOCKSIZE]; 590213068Spjd}; 591213068Spjd 592213068Spjdvoid 593213068Spjdaes_xts_reinit(caddr_t key, u_int8_t *iv) 594213068Spjd{ 595213068Spjd struct aes_xts_ctx *ctx = (struct aes_xts_ctx *)key; 596213068Spjd u_int64_t blocknum; 597213068Spjd u_int i; 598213068Spjd 599213068Spjd /* 600213068Spjd * Prepare tweak as E_k2(IV). IV is specified as LE representation 601213068Spjd * of a 64-bit block number which we allow to be passed in directly. 602213068Spjd */ 603213068Spjd bcopy(iv, &blocknum, AES_XTS_IVSIZE); 604213068Spjd for (i = 0; i < AES_XTS_IVSIZE; i++) { 605213068Spjd ctx->tweak[i] = blocknum & 0xff; 606213068Spjd blocknum >>= 8; 607213068Spjd } 608213068Spjd /* Last 64 bits of IV are always zero */ 609213068Spjd bzero(ctx->tweak + AES_XTS_IVSIZE, AES_XTS_IVSIZE); 610213068Spjd 611213068Spjd rijndael_encrypt(&ctx->key2, ctx->tweak, ctx->tweak); 612213068Spjd} 613213068Spjd 614169425Sgnnstatic void 615213068Spjdaes_xts_crypt(struct aes_xts_ctx *ctx, u_int8_t *data, u_int do_encrypt) 616213068Spjd{ 617213068Spjd u_int8_t block[AES_XTS_BLOCKSIZE]; 618213068Spjd u_int i, carry_in, carry_out; 619213068Spjd 620213068Spjd for (i = 0; i < AES_XTS_BLOCKSIZE; i++) 621213068Spjd block[i] = data[i] ^ ctx->tweak[i]; 622213068Spjd 623213068Spjd if (do_encrypt) 624213068Spjd rijndael_encrypt(&ctx->key1, block, data); 625213068Spjd else 626213068Spjd rijndael_decrypt(&ctx->key1, block, data); 627213068Spjd 628213068Spjd for (i = 0; i < AES_XTS_BLOCKSIZE; i++) 629213068Spjd data[i] ^= ctx->tweak[i]; 630213068Spjd 631213068Spjd /* Exponentiate tweak */ 632213068Spjd carry_in = 0; 633213068Spjd for (i = 0; i < AES_XTS_BLOCKSIZE; i++) { 634213068Spjd carry_out = ctx->tweak[i] & 0x80; 635213068Spjd ctx->tweak[i] = (ctx->tweak[i] << 1) | (carry_in ? 1 : 0); 636213068Spjd carry_in = carry_out; 637213068Spjd } 638213068Spjd if (carry_in) 639213068Spjd ctx->tweak[0] ^= AES_XTS_ALPHA; 640213068Spjd bzero(block, sizeof(block)); 641213068Spjd} 642213068Spjd 643213068Spjdvoid 644213068Spjdaes_xts_encrypt(caddr_t key, u_int8_t *data) 645213068Spjd{ 646213068Spjd aes_xts_crypt((struct aes_xts_ctx *)key, data, 1); 647213068Spjd} 648213068Spjd 649213068Spjdvoid 650213068Spjdaes_xts_decrypt(caddr_t key, u_int8_t *data) 651213068Spjd{ 652213068Spjd aes_xts_crypt((struct aes_xts_ctx *)key, data, 0); 653213068Spjd} 654213068Spjd 655213068Spjdint 656213068Spjdaes_xts_setkey(u_int8_t **sched, u_int8_t *key, int len) 657213068Spjd{ 658213068Spjd struct aes_xts_ctx *ctx; 659213068Spjd 660213068Spjd if (len != 32 && len != 64) 661213068Spjd return EINVAL; 662213068Spjd 663213068Spjd *sched = malloc(sizeof(struct aes_xts_ctx), M_CRYPTO_DATA, 664213068Spjd M_NOWAIT | M_ZERO); 665213068Spjd if (*sched == NULL) 666213068Spjd return ENOMEM; 667213068Spjd ctx = (struct aes_xts_ctx *)*sched; 668213068Spjd 669213068Spjd rijndael_set_key(&ctx->key1, key, len * 4); 670213068Spjd rijndael_set_key(&ctx->key2, key + (len / 2), len * 4); 671213068Spjd 672213068Spjd return 0; 673213068Spjd} 674213068Spjd 675213068Spjdvoid 676213068Spjdaes_xts_zerokey(u_int8_t **sched) 677213068Spjd{ 678213068Spjd bzero(*sched, sizeof(struct aes_xts_ctx)); 679213068Spjd free(*sched, M_CRYPTO_DATA); 680213068Spjd *sched = NULL; 681213068Spjd} 682213068Spjd 683213068Spjdstatic void 684169425Sgnncml_encrypt(caddr_t key, u_int8_t *blk) 685169425Sgnn{ 686169425Sgnn camellia_encrypt((camellia_ctx *) key, (u_char *) blk, (u_char *) blk); 687169425Sgnn} 688169425Sgnn 689169425Sgnnstatic void 690169425Sgnncml_decrypt(caddr_t key, u_int8_t *blk) 691169425Sgnn{ 692169425Sgnn camellia_decrypt(((camellia_ctx *) key), (u_char *) blk, 693169425Sgnn (u_char *) blk); 694169425Sgnn} 695169425Sgnn 696169425Sgnnstatic int 697169425Sgnncml_setkey(u_int8_t **sched, u_int8_t *key, int len) 698169425Sgnn{ 699169425Sgnn int err; 700169425Sgnn 701169425Sgnn if (len != 16 && len != 24 && len != 32) 702169425Sgnn return (EINVAL); 703184205Sdes *sched = malloc(sizeof(camellia_ctx), M_CRYPTO_DATA, 704169425Sgnn M_NOWAIT|M_ZERO); 705169425Sgnn if (*sched != NULL) { 706169425Sgnn camellia_set_key((camellia_ctx *) *sched, (u_char *) key, 707169425Sgnn len * 8); 708169425Sgnn err = 0; 709169425Sgnn } else 710169425Sgnn err = ENOMEM; 711169425Sgnn return err; 712169425Sgnn} 713169425Sgnn 714169425Sgnnstatic void 715169425Sgnncml_zerokey(u_int8_t **sched) 716169425Sgnn{ 717169425Sgnn bzero(*sched, sizeof(camellia_ctx)); 718184205Sdes free(*sched, M_CRYPTO_DATA); 719169425Sgnn *sched = NULL; 720169425Sgnn} 721169425Sgnn 722104476Ssam/* 723104476Ssam * And now for auth. 724104476Ssam */ 725104476Ssam 726104476Ssamstatic void 727104476Ssamnull_init(void *ctx) 728104476Ssam{ 729104476Ssam} 730104476Ssam 731104476Ssamstatic int 732104476Ssamnull_update(void *ctx, u_int8_t *buf, u_int16_t len) 733104476Ssam{ 734104476Ssam return 0; 735104476Ssam} 736104476Ssam 737104476Ssamstatic void 738104476Ssamnull_final(u_int8_t *buf, void *ctx) 739104476Ssam{ 740104476Ssam if (buf != (u_int8_t *) 0) 741104476Ssam bzero(buf, 12); 742104476Ssam} 743104476Ssam 744104476Ssamstatic int 745104476SsamRMD160Update_int(void *ctx, u_int8_t *buf, u_int16_t len) 746104476Ssam{ 747104476Ssam RMD160Update(ctx, buf, len); 748104476Ssam return 0; 749104476Ssam} 750104476Ssam 751104476Ssamstatic int 752104476SsamMD5Update_int(void *ctx, u_int8_t *buf, u_int16_t len) 753104476Ssam{ 754104476Ssam MD5Update(ctx, buf, len); 755104476Ssam return 0; 756104476Ssam} 757104476Ssam 758104476Ssamstatic void 759104476SsamSHA1Init_int(void *ctx) 760104476Ssam{ 761104476Ssam SHA1Init(ctx); 762104476Ssam} 763104476Ssam 764104476Ssamstatic int 765104476SsamSHA1Update_int(void *ctx, u_int8_t *buf, u_int16_t len) 766104476Ssam{ 767104476Ssam SHA1Update(ctx, buf, len); 768104476Ssam return 0; 769104476Ssam} 770104476Ssam 771104476Ssamstatic void 772104476SsamSHA1Final_int(u_int8_t *blk, void *ctx) 773104476Ssam{ 774104476Ssam SHA1Final(blk, ctx); 775104476Ssam} 776104476Ssam 777104476Ssamstatic int 778104476SsamSHA256Update_int(void *ctx, u_int8_t *buf, u_int16_t len) 779104476Ssam{ 780104476Ssam SHA256_Update(ctx, buf, len); 781104476Ssam return 0; 782104476Ssam} 783104476Ssam 784104476Ssamstatic int 785104476SsamSHA384Update_int(void *ctx, u_int8_t *buf, u_int16_t len) 786104476Ssam{ 787104476Ssam SHA384_Update(ctx, buf, len); 788104476Ssam return 0; 789104476Ssam} 790104476Ssam 791104476Ssamstatic int 792104476SsamSHA512Update_int(void *ctx, u_int8_t *buf, u_int16_t len) 793104476Ssam{ 794104476Ssam SHA512_Update(ctx, buf, len); 795104476Ssam return 0; 796104476Ssam} 797104476Ssam 798104476Ssam/* 799104476Ssam * And compression 800104476Ssam */ 801104476Ssam 802104476Ssamstatic u_int32_t 803104476Ssamdeflate_compress(data, size, out) 804104476Ssam u_int8_t *data; 805104476Ssam u_int32_t size; 806104476Ssam u_int8_t **out; 807104476Ssam{ 808104476Ssam return deflate_global(data, size, 0, out); 809104476Ssam} 810104476Ssam 811104476Ssamstatic u_int32_t 812104476Ssamdeflate_decompress(data, size, out) 813104476Ssam u_int8_t *data; 814104476Ssam u_int32_t size; 815104476Ssam u_int8_t **out; 816104476Ssam{ 817104476Ssam return deflate_global(data, size, 1, out); 818104476Ssam} 819