1 /*- 2 * Copyright (c) 2005-2011 Pawel Jakub Dawidek <pawel@dawidek.net> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #ifndef _G_ELI_H_ 30 #define _G_ELI_H_ 31 32 #include <sys/endian.h> 33 #include <sys/errno.h> 34 #include <sys/malloc.h> 35 #include <crypto/sha2/sha2.h> 36 #include <opencrypto/cryptodev.h> 37 #ifdef _KERNEL 38 #include <sys/bio.h> 39 #include <sys/libkern.h> 40 #include <sys/lock.h> 41 #include <sys/mutex.h> 42 #include <sys/queue.h> 43 #include <sys/tree.h> 44 #include <geom/geom.h> 45 #else 46 #include <assert.h> 47 #include <stdio.h> 48 #include <string.h> 49 #include <strings.h> 50 #endif 51 #ifndef _OpenSSL_ 52 #include <sys/md5.h> 53 #endif 54 55 #define G_ELI_CLASS_NAME "ELI" 56 #define G_ELI_MAGIC "GEOM::ELI" 57 #define G_ELI_SUFFIX ".eli" 58 59 /* 60 * Version history: 61 * 0 - Initial version number. 62 * 1 - Added data authentication support (md_aalgo field and 63 * G_ELI_FLAG_AUTH flag). 64 * 2 - Added G_ELI_FLAG_READONLY. 65 * 3 - Added 'configure' subcommand. 66 * 4 - IV is generated from offset converted to little-endian 67 * (the G_ELI_FLAG_NATIVE_BYTE_ORDER flag will be set for older versions). 68 * 5 - Added multiple encrypton keys and AES-XTS support. 69 * 6 - Fixed usage of multiple keys for authenticated providers (the 70 * G_ELI_FLAG_FIRST_KEY flag will be set for older versions). 71 * 7 - Encryption keys are now generated from the Data Key and not from the 72 * IV Key (the G_ELI_FLAG_ENC_IVKEY flag will be set for older versions). 73 */ 74 #define G_ELI_VERSION_00 0 75 #define G_ELI_VERSION_01 1 76 #define G_ELI_VERSION_02 2 77 #define G_ELI_VERSION_03 3 78 #define G_ELI_VERSION_04 4 79 #define G_ELI_VERSION_05 5 80 #define G_ELI_VERSION_06 6 81 #define G_ELI_VERSION_07 7 82 #define G_ELI_VERSION G_ELI_VERSION_07 83 84 /* ON DISK FLAGS. */ 85 /* Use random, onetime keys. */ 86 #define G_ELI_FLAG_ONETIME 0x00000001 87 /* Ask for the passphrase from the kernel, before mounting root. */ 88 #define G_ELI_FLAG_BOOT 0x00000002 89 /* Detach on last close, if we were open for writing. */ 90 #define G_ELI_FLAG_WO_DETACH 0x00000004 91 /* Detach on last close. */ 92 #define G_ELI_FLAG_RW_DETACH 0x00000008 93 /* Provide data authentication. */ 94 #define G_ELI_FLAG_AUTH 0x00000010 95 /* Provider is read-only, we should deny all write attempts. */ 96 #define G_ELI_FLAG_RO 0x00000020 97 /* RUNTIME FLAGS. */ 98 /* Provider was open for writing. */ 99 #define G_ELI_FLAG_WOPEN 0x00010000 100 /* Destroy device. */ 101 #define G_ELI_FLAG_DESTROY 0x00020000 102 /* Provider uses native byte-order for IV generation. */ 103 #define G_ELI_FLAG_NATIVE_BYTE_ORDER 0x00040000 104 /* Provider uses single encryption key. */ 105 #define G_ELI_FLAG_SINGLE_KEY 0x00080000 106 /* Device suspended. */ 107 #define G_ELI_FLAG_SUSPEND 0x00100000 108 /* Provider uses first encryption key. */ 109 #define G_ELI_FLAG_FIRST_KEY 0x00200000 110 /* Provider uses IV-Key for encryption key generation. */ 111 #define G_ELI_FLAG_ENC_IVKEY 0x00400000 112 113 #define G_ELI_NEW_BIO 255 114 115 #define SHA512_MDLEN 64 116 #define G_ELI_AUTH_SECKEYLEN SHA256_DIGEST_LENGTH 117 118 #define G_ELI_MAXMKEYS 2 119 #define G_ELI_MAXKEYLEN 64 120 #define G_ELI_USERKEYLEN G_ELI_MAXKEYLEN 121 #define G_ELI_DATAKEYLEN G_ELI_MAXKEYLEN 122 #define G_ELI_AUTHKEYLEN G_ELI_MAXKEYLEN 123 #define G_ELI_IVKEYLEN G_ELI_MAXKEYLEN 124 #define G_ELI_SALTLEN 64 125 #define G_ELI_DATAIVKEYLEN (G_ELI_DATAKEYLEN + G_ELI_IVKEYLEN) 126 /* Data-Key, IV-Key, HMAC_SHA512(Derived-Key, Data-Key+IV-Key) */ 127 #define G_ELI_MKEYLEN (G_ELI_DATAIVKEYLEN + SHA512_MDLEN) 128 #define G_ELI_OVERWRITES 5 129 /* Switch data encryption key every 2^20 blocks. */ 130 #define G_ELI_KEY_SHIFT 20 131 132 #ifdef _KERNEL 133 extern int g_eli_debug; 134 extern u_int g_eli_overwrites; 135 extern u_int g_eli_batch; 136 137 #define G_ELI_CRYPTO_UNKNOWN 0 138 #define G_ELI_CRYPTO_HW 1 139 #define G_ELI_CRYPTO_SW 2 140 141 #define G_ELI_DEBUG(lvl, ...) do { \ 142 if (g_eli_debug >= (lvl)) { \ 143 printf("GEOM_ELI"); \ 144 if (g_eli_debug > 0) \ 145 printf("[%u]", lvl); \ 146 printf(": "); \ 147 printf(__VA_ARGS__); \ 148 printf("\n"); \ 149 } \ 150 } while (0) 151 #define G_ELI_LOGREQ(lvl, bp, ...) do { \ 152 if (g_eli_debug >= (lvl)) { \ 153 printf("GEOM_ELI"); \ 154 if (g_eli_debug > 0) \ 155 printf("[%u]", lvl); \ 156 printf(": "); \ 157 printf(__VA_ARGS__); \ 158 printf(" "); \ 159 g_print_bio(bp); \ 160 printf("\n"); \ 161 } \ 162 } while (0) 163 164 struct g_eli_worker { 165 struct g_eli_softc *w_softc; 166 struct proc *w_proc; 167 u_int w_number; 168 uint64_t w_sid; 169 boolean_t w_active; 170 LIST_ENTRY(g_eli_worker) w_next; 171 }; 172 173 struct g_eli_softc { 174 struct g_geom *sc_geom; 175 u_int sc_version; 176 u_int sc_crypto; 177 uint8_t sc_mkey[G_ELI_DATAIVKEYLEN]; 178 uint8_t sc_ekey[G_ELI_DATAKEYLEN]; 179 TAILQ_HEAD(, g_eli_key) sc_ekeys_queue; 180 RB_HEAD(g_eli_key_tree, g_eli_key) sc_ekeys_tree; 181 struct mtx sc_ekeys_lock; 182 uint64_t sc_ekeys_total; 183 uint64_t sc_ekeys_allocated; 184 u_int sc_ealgo; 185 u_int sc_ekeylen; 186 uint8_t sc_akey[G_ELI_AUTHKEYLEN]; 187 u_int sc_aalgo; 188 u_int sc_akeylen; 189 u_int sc_alen; 190 SHA256_CTX sc_akeyctx; 191 uint8_t sc_ivkey[G_ELI_IVKEYLEN]; 192 SHA256_CTX sc_ivctx; 193 int sc_nkey; 194 uint32_t sc_flags; 195 int sc_inflight; 196 off_t sc_mediasize; 197 size_t sc_sectorsize; 198 u_int sc_bytes_per_sector; 199 u_int sc_data_per_sector; 200 boolean_t sc_cpubind; 201 202 /* Only for software cryptography. */ 203 struct bio_queue_head sc_queue; 204 struct mtx sc_queue_mtx; 205 LIST_HEAD(, g_eli_worker) sc_workers; 206 }; 207 #define sc_name sc_geom->name 208 #endif /* _KERNEL */ 209 210 struct g_eli_metadata { 211 char md_magic[16]; /* Magic value. */ 212 uint32_t md_version; /* Version number. */ 213 uint32_t md_flags; /* Additional flags. */ 214 uint16_t md_ealgo; /* Encryption algorithm. */ 215 uint16_t md_keylen; /* Key length. */ 216 uint16_t md_aalgo; /* Authentication algorithm. */ 217 uint64_t md_provsize; /* Provider's size. */ 218 uint32_t md_sectorsize; /* Sector size. */ 219 uint8_t md_keys; /* Available keys. */ 220 int32_t md_iterations; /* Number of iterations for PKCS#5v2. */ 221 uint8_t md_salt[G_ELI_SALTLEN]; /* Salt. */ 222 /* Encrypted master key (IV-key, Data-key, HMAC). */ 223 uint8_t md_mkeys[G_ELI_MAXMKEYS * G_ELI_MKEYLEN]; 224 u_char md_hash[16]; /* MD5 hash. */ 225 } __packed; 226 #ifndef _OpenSSL_ 227 static __inline void 228 eli_metadata_encode_v0(struct g_eli_metadata *md, u_char **datap) 229 { 230 u_char *p; 231 232 p = *datap; 233 le32enc(p, md->md_flags); p += sizeof(md->md_flags); 234 le16enc(p, md->md_ealgo); p += sizeof(md->md_ealgo); 235 le16enc(p, md->md_keylen); p += sizeof(md->md_keylen); 236 le64enc(p, md->md_provsize); p += sizeof(md->md_provsize); 237 le32enc(p, md->md_sectorsize); p += sizeof(md->md_sectorsize); 238 *p = md->md_keys; p += sizeof(md->md_keys); 239 le32enc(p, md->md_iterations); p += sizeof(md->md_iterations); 240 bcopy(md->md_salt, p, sizeof(md->md_salt)); p += sizeof(md->md_salt); 241 bcopy(md->md_mkeys, p, sizeof(md->md_mkeys)); p += sizeof(md->md_mkeys); 242 *datap = p; 243 } 244 static __inline void 245 eli_metadata_encode_v1v2v3v4v5v6v7(struct g_eli_metadata *md, u_char **datap) 246 { 247 u_char *p; 248 249 p = *datap; 250 le32enc(p, md->md_flags); p += sizeof(md->md_flags); 251 le16enc(p, md->md_ealgo); p += sizeof(md->md_ealgo); 252 le16enc(p, md->md_keylen); p += sizeof(md->md_keylen); 253 le16enc(p, md->md_aalgo); p += sizeof(md->md_aalgo); 254 le64enc(p, md->md_provsize); p += sizeof(md->md_provsize); 255 le32enc(p, md->md_sectorsize); p += sizeof(md->md_sectorsize); 256 *p = md->md_keys; p += sizeof(md->md_keys); 257 le32enc(p, md->md_iterations); p += sizeof(md->md_iterations); 258 bcopy(md->md_salt, p, sizeof(md->md_salt)); p += sizeof(md->md_salt); 259 bcopy(md->md_mkeys, p, sizeof(md->md_mkeys)); p += sizeof(md->md_mkeys); 260 *datap = p; 261 } 262 static __inline void 263 eli_metadata_encode(struct g_eli_metadata *md, u_char *data) 264 { 265 MD5_CTX ctx; 266 u_char *p; 267 268 p = data; 269 bcopy(md->md_magic, p, sizeof(md->md_magic)); 270 p += sizeof(md->md_magic); 271 le32enc(p, md->md_version); 272 p += sizeof(md->md_version); 273 switch (md->md_version) { 274 case G_ELI_VERSION_00: 275 eli_metadata_encode_v0(md, &p); 276 break; 277 case G_ELI_VERSION_01: 278 case G_ELI_VERSION_02: 279 case G_ELI_VERSION_03: 280 case G_ELI_VERSION_04: 281 case G_ELI_VERSION_05: 282 case G_ELI_VERSION_06: 283 case G_ELI_VERSION_07: 284 eli_metadata_encode_v1v2v3v4v5v6v7(md, &p); 285 break; 286 default: 287 #ifdef _KERNEL 288 panic("%s: Unsupported version %u.", __func__, 289 (u_int)md->md_version); 290 #else 291 assert(!"Unsupported metadata version."); 292 #endif 293 } 294 MD5Init(&ctx); 295 MD5Update(&ctx, data, p - data); 296 MD5Final(md->md_hash, &ctx); 297 bcopy(md->md_hash, p, sizeof(md->md_hash)); 298 } 299 static __inline int 300 eli_metadata_decode_v0(const u_char *data, struct g_eli_metadata *md) 301 { 302 MD5_CTX ctx; 303 const u_char *p; 304 305 p = data + sizeof(md->md_magic) + sizeof(md->md_version); 306 md->md_flags = le32dec(p); p += sizeof(md->md_flags); 307 md->md_ealgo = le16dec(p); p += sizeof(md->md_ealgo); 308 md->md_keylen = le16dec(p); p += sizeof(md->md_keylen); 309 md->md_provsize = le64dec(p); p += sizeof(md->md_provsize); 310 md->md_sectorsize = le32dec(p); p += sizeof(md->md_sectorsize); 311 md->md_keys = *p; p += sizeof(md->md_keys); 312 md->md_iterations = le32dec(p); p += sizeof(md->md_iterations); 313 bcopy(p, md->md_salt, sizeof(md->md_salt)); p += sizeof(md->md_salt); 314 bcopy(p, md->md_mkeys, sizeof(md->md_mkeys)); p += sizeof(md->md_mkeys); 315 MD5Init(&ctx); 316 MD5Update(&ctx, data, p - data); 317 MD5Final(md->md_hash, &ctx); 318 if (bcmp(md->md_hash, p, 16) != 0) 319 return (EINVAL); 320 return (0); 321 } 322 323 static __inline int 324 eli_metadata_decode_v1v2v3v4v5v6v7(const u_char *data, struct g_eli_metadata *md) 325 { 326 MD5_CTX ctx; 327 const u_char *p; 328 329 p = data + sizeof(md->md_magic) + sizeof(md->md_version); 330 md->md_flags = le32dec(p); p += sizeof(md->md_flags); 331 md->md_ealgo = le16dec(p); p += sizeof(md->md_ealgo); 332 md->md_keylen = le16dec(p); p += sizeof(md->md_keylen); 333 md->md_aalgo = le16dec(p); p += sizeof(md->md_aalgo); 334 md->md_provsize = le64dec(p); p += sizeof(md->md_provsize); 335 md->md_sectorsize = le32dec(p); p += sizeof(md->md_sectorsize); 336 md->md_keys = *p; p += sizeof(md->md_keys); 337 md->md_iterations = le32dec(p); p += sizeof(md->md_iterations); 338 bcopy(p, md->md_salt, sizeof(md->md_salt)); p += sizeof(md->md_salt); 339 bcopy(p, md->md_mkeys, sizeof(md->md_mkeys)); p += sizeof(md->md_mkeys); 340 MD5Init(&ctx); 341 MD5Update(&ctx, data, p - data); 342 MD5Final(md->md_hash, &ctx); 343 if (bcmp(md->md_hash, p, 16) != 0) 344 return (EINVAL); 345 return (0); 346 } 347 static __inline int 348 eli_metadata_decode(const u_char *data, struct g_eli_metadata *md) 349 { 350 int error; 351 352 bcopy(data, md->md_magic, sizeof(md->md_magic)); 353 if (strcmp(md->md_magic, G_ELI_MAGIC) != 0) 354 return (EINVAL); 355 md->md_version = le32dec(data + sizeof(md->md_magic)); 356 switch (md->md_version) { 357 case G_ELI_VERSION_00: 358 error = eli_metadata_decode_v0(data, md); 359 break; 360 case G_ELI_VERSION_01: 361 case G_ELI_VERSION_02: 362 case G_ELI_VERSION_03: 363 case G_ELI_VERSION_04: 364 case G_ELI_VERSION_05: 365 case G_ELI_VERSION_06: 366 case G_ELI_VERSION_07: 367 error = eli_metadata_decode_v1v2v3v4v5v6v7(data, md); 368 break; 369 default: 370 error = EOPNOTSUPP; 371 break; 372 } 373 return (error); 374 } 375 #endif /* !_OpenSSL */ 376 377 static __inline u_int 378 g_eli_str2ealgo(const char *name) 379 { 380 381 if (strcasecmp("null", name) == 0) 382 return (CRYPTO_NULL_CBC); 383 else if (strcasecmp("null-cbc", name) == 0) 384 return (CRYPTO_NULL_CBC); 385 else if (strcasecmp("aes", name) == 0) 386 return (CRYPTO_AES_XTS); 387 else if (strcasecmp("aes-cbc", name) == 0) 388 return (CRYPTO_AES_CBC); 389 else if (strcasecmp("aes-xts", name) == 0) 390 return (CRYPTO_AES_XTS); 391 else if (strcasecmp("blowfish", name) == 0) 392 return (CRYPTO_BLF_CBC); 393 else if (strcasecmp("blowfish-cbc", name) == 0) 394 return (CRYPTO_BLF_CBC); 395 else if (strcasecmp("camellia", name) == 0) 396 return (CRYPTO_CAMELLIA_CBC); 397 else if (strcasecmp("camellia-cbc", name) == 0) 398 return (CRYPTO_CAMELLIA_CBC); 399 else if (strcasecmp("3des", name) == 0) 400 return (CRYPTO_3DES_CBC); 401 else if (strcasecmp("3des-cbc", name) == 0) 402 return (CRYPTO_3DES_CBC); 403 return (CRYPTO_ALGORITHM_MIN - 1); 404 } 405 406 static __inline u_int 407 g_eli_str2aalgo(const char *name) 408 { 409 410 if (strcasecmp("hmac/md5", name) == 0) 411 return (CRYPTO_MD5_HMAC); 412 else if (strcasecmp("hmac/sha1", name) == 0) 413 return (CRYPTO_SHA1_HMAC); 414 else if (strcasecmp("hmac/ripemd160", name) == 0) 415 return (CRYPTO_RIPEMD160_HMAC); 416 else if (strcasecmp("hmac/sha256", name) == 0) 417 return (CRYPTO_SHA2_256_HMAC); 418 else if (strcasecmp("hmac/sha384", name) == 0) 419 return (CRYPTO_SHA2_384_HMAC); 420 else if (strcasecmp("hmac/sha512", name) == 0) 421 return (CRYPTO_SHA2_512_HMAC); 422 return (CRYPTO_ALGORITHM_MIN - 1); 423 } 424 425 static __inline const char * 426 g_eli_algo2str(u_int algo) 427 { 428 429 switch (algo) { 430 case CRYPTO_NULL_CBC: 431 return ("NULL"); 432 case CRYPTO_AES_CBC: 433 return ("AES-CBC"); 434 case CRYPTO_AES_XTS: 435 return ("AES-XTS"); 436 case CRYPTO_BLF_CBC: 437 return ("Blowfish-CBC"); 438 case CRYPTO_CAMELLIA_CBC: 439 return ("CAMELLIA-CBC"); 440 case CRYPTO_3DES_CBC: 441 return ("3DES-CBC"); 442 case CRYPTO_MD5_HMAC: 443 return ("HMAC/MD5"); 444 case CRYPTO_SHA1_HMAC: 445 return ("HMAC/SHA1"); 446 case CRYPTO_RIPEMD160_HMAC: 447 return ("HMAC/RIPEMD160"); 448 case CRYPTO_SHA2_256_HMAC: 449 return ("HMAC/SHA256"); 450 case CRYPTO_SHA2_384_HMAC: 451 return ("HMAC/SHA384"); 452 case CRYPTO_SHA2_512_HMAC: 453 return ("HMAC/SHA512"); 454 } 455 return ("unknown"); 456 } 457 458 static __inline void 459 eli_metadata_dump(const struct g_eli_metadata *md) 460 { 461 static const char hex[] = "0123456789abcdef"; 462 char str[sizeof(md->md_mkeys) * 2 + 1]; 463 u_int i; 464 465 printf(" magic: %s\n", md->md_magic); 466 printf(" version: %u\n", (u_int)md->md_version); 467 printf(" flags: 0x%x\n", (u_int)md->md_flags); 468 printf(" ealgo: %s\n", g_eli_algo2str(md->md_ealgo)); 469 printf(" keylen: %u\n", (u_int)md->md_keylen); 470 if (md->md_flags & G_ELI_FLAG_AUTH) 471 printf(" aalgo: %s\n", g_eli_algo2str(md->md_aalgo)); 472 printf(" provsize: %ju\n", (uintmax_t)md->md_provsize); 473 printf("sectorsize: %u\n", (u_int)md->md_sectorsize); 474 printf(" keys: 0x%02x\n", (u_int)md->md_keys); 475 printf("iterations: %u\n", (u_int)md->md_iterations); 476 bzero(str, sizeof(str)); 477 for (i = 0; i < sizeof(md->md_salt); i++) { 478 str[i * 2] = hex[md->md_salt[i] >> 4]; 479 str[i * 2 + 1] = hex[md->md_salt[i] & 0x0f]; 480 } 481 printf(" Salt: %s\n", str); 482 bzero(str, sizeof(str)); 483 for (i = 0; i < sizeof(md->md_mkeys); i++) { 484 str[i * 2] = hex[md->md_mkeys[i] >> 4]; 485 str[i * 2 + 1] = hex[md->md_mkeys[i] & 0x0f]; 486 } 487 printf("Master Key: %s\n", str); 488 bzero(str, sizeof(str)); 489 for (i = 0; i < 16; i++) { 490 str[i * 2] = hex[md->md_hash[i] >> 4]; 491 str[i * 2 + 1] = hex[md->md_hash[i] & 0x0f]; 492 } 493 printf(" MD5 hash: %s\n", str); 494 } 495 496 static __inline u_int 497 g_eli_keylen(u_int algo, u_int keylen) 498 { 499 500 switch (algo) { 501 case CRYPTO_NULL_CBC: 502 if (keylen == 0) 503 keylen = 64 * 8; 504 else { 505 if (keylen > 64 * 8) 506 keylen = 0; 507 } 508 return (keylen); 509 case CRYPTO_AES_CBC: 510 case CRYPTO_CAMELLIA_CBC: 511 switch (keylen) { 512 case 0: 513 return (128); 514 case 128: 515 case 192: 516 case 256: 517 return (keylen); 518 default: 519 return (0); 520 } 521 case CRYPTO_AES_XTS: 522 switch (keylen) { 523 case 0: 524 return (128); 525 case 128: 526 case 256: 527 return (keylen); 528 default: 529 return (0); 530 } 531 case CRYPTO_BLF_CBC: 532 if (keylen == 0) 533 return (128); 534 if (keylen < 128 || keylen > 448) 535 return (0); 536 if ((keylen % 32) != 0) 537 return (0); 538 return (keylen); 539 case CRYPTO_3DES_CBC: 540 if (keylen == 0 || keylen == 192) 541 return (192); 542 return (0); 543 default: 544 return (0); 545 } 546 } 547 548 static __inline u_int 549 g_eli_hashlen(u_int algo) 550 { 551 552 switch (algo) { 553 case CRYPTO_MD5_HMAC: 554 return (16); 555 case CRYPTO_SHA1_HMAC: 556 return (20); 557 case CRYPTO_RIPEMD160_HMAC: 558 return (20); 559 case CRYPTO_SHA2_256_HMAC: 560 return (32); 561 case CRYPTO_SHA2_384_HMAC: 562 return (48); 563 case CRYPTO_SHA2_512_HMAC: 564 return (64); 565 } 566 return (0); 567 } 568 569 #ifdef _KERNEL 570 int g_eli_read_metadata(struct g_class *mp, struct g_provider *pp, 571 struct g_eli_metadata *md); 572 struct g_geom *g_eli_create(struct gctl_req *req, struct g_class *mp, 573 struct g_provider *bpp, const struct g_eli_metadata *md, 574 const u_char *mkey, int nkey); 575 int g_eli_destroy(struct g_eli_softc *sc, boolean_t force); 576 577 int g_eli_access(struct g_provider *pp, int dr, int dw, int de); 578 void g_eli_config(struct gctl_req *req, struct g_class *mp, const char *verb); 579 580 void g_eli_read_done(struct bio *bp); 581 void g_eli_write_done(struct bio *bp); 582 int g_eli_crypto_rerun(struct cryptop *crp); 583 void g_eli_crypto_ivgen(struct g_eli_softc *sc, off_t offset, u_char *iv, 584 size_t size); 585 586 void g_eli_crypto_read(struct g_eli_softc *sc, struct bio *bp, boolean_t fromworker); 587 void g_eli_crypto_run(struct g_eli_worker *wr, struct bio *bp); 588 589 void g_eli_auth_read(struct g_eli_softc *sc, struct bio *bp); 590 void g_eli_auth_run(struct g_eli_worker *wr, struct bio *bp); 591 #endif 592 593 void g_eli_mkey_hmac(unsigned char *mkey, const unsigned char *key); 594 int g_eli_mkey_decrypt(const struct g_eli_metadata *md, 595 const unsigned char *key, unsigned char *mkey, unsigned *nkeyp); 596 int g_eli_mkey_encrypt(unsigned algo, const unsigned char *key, unsigned keylen, 597 unsigned char *mkey); 598 #ifdef _KERNEL 599 void g_eli_mkey_propagate(struct g_eli_softc *sc, const unsigned char *mkey); 600 #endif 601 602 int g_eli_crypto_encrypt(u_int algo, u_char *data, size_t datasize, 603 const u_char *key, size_t keysize); 604 int g_eli_crypto_decrypt(u_int algo, u_char *data, size_t datasize, 605 const u_char *key, size_t keysize); 606 607 struct hmac_ctx { 608 SHA512_CTX shactx; 609 u_char k_opad[128]; 610 }; 611 612 void g_eli_crypto_hmac_init(struct hmac_ctx *ctx, const uint8_t *hkey, 613 size_t hkeylen); 614 void g_eli_crypto_hmac_update(struct hmac_ctx *ctx, const uint8_t *data, 615 size_t datasize); 616 void g_eli_crypto_hmac_final(struct hmac_ctx *ctx, uint8_t *md, size_t mdsize); 617 void g_eli_crypto_hmac(const uint8_t *hkey, size_t hkeysize, 618 const uint8_t *data, size_t datasize, uint8_t *md, size_t mdsize); 619 620 #ifdef _KERNEL 621 void g_eli_key_init(struct g_eli_softc *sc); 622 void g_eli_key_destroy(struct g_eli_softc *sc); 623 uint8_t *g_eli_key_hold(struct g_eli_softc *sc, off_t offset, size_t blocksize); 624 void g_eli_key_drop(struct g_eli_softc *sc, uint8_t *rawkey); 625 #endif 626 #endif /* !_G_ELI_H_ */ 627