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