g_eli.h revision 213070
11897Swollman/*- 21897Swollman * Copyright (c) 2005-2006 Pawel Jakub Dawidek <pjd@FreeBSD.org> 31897Swollman * All rights reserved. 41897Swollman * 51897Swollman * Redistribution and use in source and binary forms, with or without 61897Swollman * modification, are permitted provided that the following conditions 71897Swollman * are met: 8100441Scharnier * 1. Redistributions of source code must retain the above copyright 91897Swollman * notice, this list of conditions and the following disclaimer. 101897Swollman * 2. Redistributions in binary form must reproduce the above copyright 111897Swollman * notice, this list of conditions and the following disclaimer in the 12100441Scharnier * documentation and/or other materials provided with the distribution. 131897Swollman * 141897Swollman * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 151897Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16100441Scharnier * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 171897Swollman * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 181897Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 191897Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20100441Scharnier * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 211897Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 221897Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 231897Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24100441Scharnier * SUCH DAMAGE. 251897Swollman * 261897Swollman * $FreeBSD: head/sys/geom/eli/g_eli.h 213070 2010-09-23 11:58:36Z pjd $ 271897Swollman */ 281897Swollman 2912798Swpaul#ifndef _G_ELI_H_ 30100441Scharnier#define _G_ELI_H_ 311897Swollman 32146833Sstefanf#include <sys/endian.h> 3312798Swpaul#include <sys/errno.h> 341897Swollman#include <sys/malloc.h> 3527935Scharnier#include <crypto/sha2/sha2.h> 361897Swollman#include <opencrypto/cryptodev.h> 37100441Scharnier#ifdef _KERNEL 38100441Scharnier#include <sys/bio.h> 39100441Scharnier#include <sys/libkern.h> 401897Swollman#include <geom/geom.h> 418874Srgrimes#else 4212798Swpaul#include <stdio.h> 431897Swollman#include <string.h> 4427935Scharnier#include <strings.h> 45200462Sdelphij#endif 461897Swollman#ifndef _OpenSSL_ 4717142Sjkh#include <sys/md5.h> 4817142Sjkh#endif 49152398Sdwmalone 501897Swollman#define G_ELI_CLASS_NAME "ELI" 511897Swollman#define G_ELI_MAGIC "GEOM::ELI" 521897Swollman#define G_ELI_SUFFIX ".eli" 5312798Swpaul 5412798Swpaul/* 551897Swollman * Version history: 5612798Swpaul * 0 - Initial version number. 5712798Swpaul * 1 - Added data authentication support (md_aalgo field and 581897Swollman * G_ELI_FLAG_AUTH flag). 59152398Sdwmalone * 2 - Added G_ELI_FLAG_READONLY. 601897Swollman * 3 - Added 'configure' subcommand. 6112798Swpaul * 4 - IV is generated from offset converted to little-endian 62241737Sed * (flag G_ELI_FLAG_NATIVE_BYTE_ORDER will be set for older versions). 63241737Sed * 5 - Added multiple encrypton keys and AES-XTS support. 641897Swollman */ 6512798Swpaul#define G_ELI_VERSION 5 6612798Swpaul 671897Swollman/* ON DISK FLAGS. */ 6812798Swpaul/* Use random, onetime keys. */ 691897Swollman#define G_ELI_FLAG_ONETIME 0x00000001 7092921Simp/* Ask for the passphrase from the kernel, before mounting root. */ 711897Swollman#define G_ELI_FLAG_BOOT 0x00000002 721897Swollman/* Detach on last close, if we were open for writing. */ 738874Srgrimes#define G_ELI_FLAG_WO_DETACH 0x00000004 741897Swollman/* Detach on last close. */ 7517142Sjkh#define G_ELI_FLAG_RW_DETACH 0x00000008 76152398Sdwmalone/* Provide data authentication. */ 771897Swollman#define G_ELI_FLAG_AUTH 0x00000010 7812798Swpaul/* Provider is read-only, we should deny all write attempts. */ 791897Swollman#define G_ELI_FLAG_RO 0x00000020 801897Swollman/* RUNTIME FLAGS. */ 811897Swollman/* Provider was open for writing. */ 821897Swollman#define G_ELI_FLAG_WOPEN 0x00010000 831897Swollman/* Destroy device. */ 841897Swollman#define G_ELI_FLAG_DESTROY 0x00020000 858874Srgrimes/* Provider uses native byte-order for IV generation. */ 861897Swollman#define G_ELI_FLAG_NATIVE_BYTE_ORDER 0x00040000 8717142Sjkh/* Provider uses single encryption key. */ 88152398Sdwmalone#define G_ELI_FLAG_SINGLE_KEY 0x00080000 891897Swollman 901897Swollman#define SHA512_MDLEN 64 911897Swollman#define G_ELI_AUTH_SECKEYLEN SHA256_DIGEST_LENGTH 921897Swollman 931897Swollman#define G_ELI_MAXMKEYS 2 948874Srgrimes#define G_ELI_MAXKEYLEN 64 951897Swollman#define G_ELI_USERKEYLEN G_ELI_MAXKEYLEN 9612798Swpaul#define G_ELI_DATAKEYLEN G_ELI_MAXKEYLEN 97152398Sdwmalone#define G_ELI_AUTHKEYLEN G_ELI_MAXKEYLEN 981897Swollman#define G_ELI_IVKEYLEN G_ELI_MAXKEYLEN 991897Swollman#define G_ELI_SALTLEN 64 1001897Swollman#define G_ELI_DATAIVKEYLEN (G_ELI_DATAKEYLEN + G_ELI_IVKEYLEN) 1011897Swollman/* Data-Key, IV-Key, HMAC_SHA512(Derived-Key, Data-Key+IV-Key) */ 1021897Swollman#define G_ELI_MKEYLEN (G_ELI_DATAIVKEYLEN + SHA512_MDLEN) 1031897Swollman#define G_ELI_OVERWRITES 5 1041897Swollman/* Switch data encryption key every 2^20 blocks. */ 1051897Swollman#define G_ELI_KEY_SHIFT 20 1061897Swollman 1071897Swollman#ifdef _KERNEL 1088874Srgrimesextern u_int g_eli_debug; 1091897Swollmanextern u_int g_eli_overwrites; 1101897Swollmanextern u_int g_eli_batch; 111152398Sdwmalone 1121897Swollman#define G_ELI_CRYPTO_HW 1 1131897Swollman#define G_ELI_CRYPTO_SW 2 1141897Swollman 1151897Swollman#define G_ELI_DEBUG(lvl, ...) do { \ 1161897Swollman if (g_eli_debug >= (lvl)) { \ 117100441Scharnier printf("GEOM_ELI"); \ 1181897Swollman if (g_eli_debug > 0) \ 1191897Swollman printf("[%u]", lvl); \ 1201897Swollman printf(": "); \ 1211897Swollman printf(__VA_ARGS__); \ 1221897Swollman printf("\n"); \ 12317142Sjkh } \ 124152398Sdwmalone} while (0) 1251897Swollman#define G_ELI_LOGREQ(lvl, bp, ...) do { \ 1261897Swollman if (g_eli_debug >= (lvl)) { \ 1271897Swollman printf("GEOM_ELI"); \ 1281897Swollman if (g_eli_debug > 0) \ 129152398Sdwmalone printf("[%u]", lvl); \ 130152398Sdwmalone printf(": "); \ 1311897Swollman printf(__VA_ARGS__); \ 1321897Swollman printf(" "); \ 1331897Swollman g_print_bio(bp); \ 1341897Swollman printf("\n"); \ 1351897Swollman } \ 1361897Swollman} while (0) 1371897Swollman 1381897Swollmanstruct g_eli_worker { 1391897Swollman struct g_eli_softc *w_softc; 14012798Swpaul struct proc *w_proc; 14112798Swpaul u_int w_number; 14212798Swpaul uint64_t w_sid; 14312798Swpaul LIST_ENTRY(g_eli_worker) w_next; 14412798Swpaul}; 1451897Swollman 1461897Swollmanstruct g_eli_softc { 1471897Swollman struct g_geom *sc_geom; 1481897Swollman u_int sc_crypto; 1491897Swollman uint8_t sc_mkey[G_ELI_DATAIVKEYLEN]; 1501897Swollman uint8_t **sc_ekeys; 1511897Swollman u_int sc_nekeys; 152152398Sdwmalone u_int sc_ealgo; 153152398Sdwmalone u_int sc_ekeylen; 1541897Swollman uint8_t sc_akey[G_ELI_AUTHKEYLEN]; 1551897Swollman u_int sc_aalgo; 1561897Swollman u_int sc_akeylen; 1571897Swollman u_int sc_alen; 158152398Sdwmalone SHA256_CTX sc_akeyctx; 159152398Sdwmalone uint8_t sc_ivkey[G_ELI_IVKEYLEN]; 1601897Swollman SHA256_CTX sc_ivctx; 1611897Swollman int sc_nkey; 1621897Swollman uint32_t sc_flags; 1631897Swollman off_t sc_mediasize; 1641897Swollman size_t sc_sectorsize; 1651897Swollman u_int sc_bytes_per_sector; 1661897Swollman u_int sc_data_per_sector; 1671897Swollman 1681897Swollman /* Only for software cryptography. */ 169152398Sdwmalone struct bio_queue_head sc_queue; 1701897Swollman struct mtx sc_queue_mtx; 1711897Swollman LIST_HEAD(, g_eli_worker) sc_workers; 1721897Swollman}; 1731897Swollman#define sc_name sc_geom->name 1741897Swollman#endif /* _KERNEL */ 1751897Swollman 1761897Swollmanstruct g_eli_metadata { 1771897Swollman char md_magic[16]; /* Magic value. */ 1781897Swollman uint32_t md_version; /* Version number. */ 1791897Swollman uint32_t md_flags; /* Additional flags. */ 1801897Swollman uint16_t md_ealgo; /* Encryption algorithm. */ 1811897Swollman uint16_t md_keylen; /* Key length. */ 1821897Swollman uint16_t md_aalgo; /* Authentication algorithm. */ 1831897Swollman uint64_t md_provsize; /* Provider's size. */ 1841897Swollman uint32_t md_sectorsize; /* Sector size. */ 1851897Swollman uint8_t md_keys; /* Available keys. */ 1861897Swollman int32_t md_iterations; /* Number of iterations for PKCS#5v2. */ 18717142Sjkh uint8_t md_salt[G_ELI_SALTLEN]; /* Salt. */ 188152398Sdwmalone /* Encrypted master key (IV-key, Data-key, HMAC). */ 1891897Swollman uint8_t md_mkeys[G_ELI_MAXMKEYS * G_ELI_MKEYLEN]; 1901897Swollman u_char md_hash[16]; /* MD5 hash. */ 1911897Swollman} __packed; 1921897Swollman#ifndef _OpenSSL_ 1931897Swollmanstatic __inline void 1941897Swollmaneli_metadata_encode(struct g_eli_metadata *md, u_char *data) 1951897Swollman{ 1961897Swollman MD5_CTX ctx; 19717142Sjkh u_char *p; 198152398Sdwmalone 1991897Swollman p = data; 2001897Swollman bcopy(md->md_magic, p, sizeof(md->md_magic)); p += sizeof(md->md_magic); 2011897Swollman le32enc(p, md->md_version); p += sizeof(md->md_version); 2021897Swollman le32enc(p, md->md_flags); p += sizeof(md->md_flags); 2031897Swollman le16enc(p, md->md_ealgo); p += sizeof(md->md_ealgo); 2041897Swollman le16enc(p, md->md_keylen); p += sizeof(md->md_keylen); 2051897Swollman le16enc(p, md->md_aalgo); p += sizeof(md->md_aalgo); 2061897Swollman le64enc(p, md->md_provsize); p += sizeof(md->md_provsize); 2071897Swollman le32enc(p, md->md_sectorsize); p += sizeof(md->md_sectorsize); 2081897Swollman *p = md->md_keys; p += sizeof(md->md_keys); 2091897Swollman le32enc(p, md->md_iterations); p += sizeof(md->md_iterations); 2101897Swollman bcopy(md->md_salt, p, sizeof(md->md_salt)); p += sizeof(md->md_salt); 2111897Swollman bcopy(md->md_mkeys, p, sizeof(md->md_mkeys)); p += sizeof(md->md_mkeys); 2121897Swollman MD5Init(&ctx); 2131897Swollman MD5Update(&ctx, data, p - data); 2141897Swollman MD5Final(md->md_hash, &ctx); 2151897Swollman bcopy(md->md_hash, p, sizeof(md->md_hash)); 2161897Swollman} 2171897Swollmanstatic __inline int 2181897Swollmaneli_metadata_decode_v0(const u_char *data, struct g_eli_metadata *md) 21917142Sjkh{ 22017142Sjkh MD5_CTX ctx; 2211897Swollman const u_char *p; 2221897Swollman 22312798Swpaul p = data + sizeof(md->md_magic) + sizeof(md->md_version); 224152398Sdwmalone md->md_flags = le32dec(p); p += sizeof(md->md_flags); 2251897Swollman md->md_ealgo = le16dec(p); p += sizeof(md->md_ealgo); 2261897Swollman md->md_keylen = le16dec(p); p += sizeof(md->md_keylen); 2271897Swollman md->md_provsize = le64dec(p); p += sizeof(md->md_provsize); 2281897Swollman md->md_sectorsize = le32dec(p); p += sizeof(md->md_sectorsize); 2291897Swollman md->md_keys = *p; p += sizeof(md->md_keys); 23017142Sjkh md->md_iterations = le32dec(p); p += sizeof(md->md_iterations); 2311897Swollman bcopy(p, md->md_salt, sizeof(md->md_salt)); p += sizeof(md->md_salt); 2321897Swollman bcopy(p, md->md_mkeys, sizeof(md->md_mkeys)); p += sizeof(md->md_mkeys); 2331897Swollman MD5Init(&ctx); 2341897Swollman MD5Update(&ctx, data, p - data); 2351897Swollman MD5Final(md->md_hash, &ctx); 2361897Swollman if (bcmp(md->md_hash, p, 16) != 0) 23712798Swpaul return (EINVAL); 238152398Sdwmalone return (0); 23912798Swpaul} 24012798Swpaul 24112798Swpaulstatic __inline int 2421897Swollmaneli_metadata_decode_v1v2v3v4v5(const u_char *data, struct g_eli_metadata *md) 2431897Swollman{ 244152398Sdwmalone MD5_CTX ctx; 2451897Swollman const u_char *p; 2461897Swollman 2471897Swollman p = data + sizeof(md->md_magic) + sizeof(md->md_version); 2481897Swollman md->md_flags = le32dec(p); p += sizeof(md->md_flags); 2491897Swollman md->md_ealgo = le16dec(p); p += sizeof(md->md_ealgo); 2508874Srgrimes md->md_keylen = le16dec(p); p += sizeof(md->md_keylen); 2511897Swollman md->md_aalgo = le16dec(p); p += sizeof(md->md_aalgo); 2521897Swollman md->md_provsize = le64dec(p); p += sizeof(md->md_provsize); 253152398Sdwmalone md->md_sectorsize = le32dec(p); p += sizeof(md->md_sectorsize); 2541897Swollman md->md_keys = *p; p += sizeof(md->md_keys); 2551897Swollman md->md_iterations = le32dec(p); p += sizeof(md->md_iterations); 25627935Scharnier bcopy(p, md->md_salt, sizeof(md->md_salt)); p += sizeof(md->md_salt); 2571897Swollman bcopy(p, md->md_mkeys, sizeof(md->md_mkeys)); p += sizeof(md->md_mkeys); 2581897Swollman MD5Init(&ctx); 2591897Swollman MD5Update(&ctx, data, p - data); 2601897Swollman MD5Final(md->md_hash, &ctx); 2611897Swollman if (bcmp(md->md_hash, p, 16) != 0) 2628874Srgrimes return (EINVAL); 2631897Swollman return (0); 26417142Sjkh} 265152398Sdwmalonestatic __inline int 2661897Swollmaneli_metadata_decode(const u_char *data, struct g_eli_metadata *md) 2671897Swollman{ 2681897Swollman int error; 2691897Swollman 2701897Swollman bcopy(data, md->md_magic, sizeof(md->md_magic)); 2711897Swollman md->md_version = le32dec(data + sizeof(md->md_magic)); 2721897Swollman switch (md->md_version) { 2731897Swollman case 0: 2741897Swollman error = eli_metadata_decode_v0(data, md); 2751897Swollman break; 276152398Sdwmalone case 1: 2771897Swollman case 2: 2781897Swollman case 3: 2791897Swollman case 4: 2801897Swollman case 5: 28127935Scharnier error = eli_metadata_decode_v1v2v3v4v5(data, md); 2821897Swollman break; 2831897Swollman default: 2841897Swollman error = EINVAL; 2851897Swollman break; 2861897Swollman } 287152398Sdwmalone return (error); 2881897Swollman} 2891897Swollman#endif /* !_OpenSSL */ 2908874Srgrimes 2911897Swollmanstatic __inline u_int 2921897Swollmang_eli_str2ealgo(const char *name) 293152398Sdwmalone{ 2941897Swollman 2951897Swollman if (strcasecmp("null", name) == 0) 2961897Swollman return (CRYPTO_NULL_CBC); 2971897Swollman else if (strcasecmp("null-cbc", name) == 0) 2981897Swollman return (CRYPTO_NULL_CBC); 2991897Swollman else if (strcasecmp("aes", name) == 0) 3001897Swollman return (CRYPTO_AES_XTS); 3018874Srgrimes else if (strcasecmp("aes-cbc", name) == 0) 3021897Swollman return (CRYPTO_AES_CBC); 3031897Swollman else if (strcasecmp("aes-xts", name) == 0) 304152398Sdwmalone return (CRYPTO_AES_XTS); 3051897Swollman else if (strcasecmp("blowfish", name) == 0) 3061897Swollman return (CRYPTO_BLF_CBC); 3071897Swollman else if (strcasecmp("blowfish-cbc", name) == 0) 3081897Swollman return (CRYPTO_BLF_CBC); 3091897Swollman else if (strcasecmp("camellia", name) == 0) 3101897Swollman return (CRYPTO_CAMELLIA_CBC); 3111897Swollman else if (strcasecmp("camellia-cbc", name) == 0) 3121897Swollman return (CRYPTO_CAMELLIA_CBC); 3138874Srgrimes else if (strcasecmp("3des", name) == 0) 3141897Swollman return (CRYPTO_3DES_CBC); 3151897Swollman else if (strcasecmp("3des-cbc", name) == 0) 316152398Sdwmalone return (CRYPTO_3DES_CBC); 3171897Swollman return (CRYPTO_ALGORITHM_MIN - 1); 3181897Swollman} 3191897Swollman 3201897Swollmanstatic __inline u_int 3211897Swollmang_eli_str2aalgo(const char *name) 3221897Swollman{ 3231897Swollman 3241897Swollman if (strcasecmp("hmac/md5", name) == 0) 3251897Swollman return (CRYPTO_MD5_HMAC); 326152398Sdwmalone else if (strcasecmp("hmac/sha1", name) == 0) 3271897Swollman return (CRYPTO_SHA1_HMAC); 3281897Swollman else if (strcasecmp("hmac/ripemd160", name) == 0) 3291897Swollman return (CRYPTO_RIPEMD160_HMAC); 3301897Swollman else if (strcasecmp("hmac/sha256", name) == 0) 3311897Swollman return (CRYPTO_SHA2_256_HMAC); 3321897Swollman else if (strcasecmp("hmac/sha384", name) == 0) 3331897Swollman return (CRYPTO_SHA2_384_HMAC); 3341897Swollman else if (strcasecmp("hmac/sha512", name) == 0) 33512798Swpaul return (CRYPTO_SHA2_512_HMAC); 33612798Swpaul return (CRYPTO_ALGORITHM_MIN - 1); 33712798Swpaul} 33812798Swpaul 33912798Swpaulstatic __inline const char * 34012798Swpaulg_eli_algo2str(u_int algo) 34112798Swpaul{ 34212798Swpaul 34312798Swpaul switch (algo) { 34412798Swpaul case CRYPTO_NULL_CBC: 34512798Swpaul return ("NULL"); 34612798Swpaul case CRYPTO_AES_CBC: 34712798Swpaul return ("AES-CBC"); 34812798Swpaul case CRYPTO_AES_XTS: 34912798Swpaul return ("AES-XTS"); 35012798Swpaul case CRYPTO_BLF_CBC: 35112798Swpaul return ("Blowfish-CBC"); 35212798Swpaul case CRYPTO_CAMELLIA_CBC: 35312798Swpaul return ("CAMELLIA-CBC"); 35412798Swpaul case CRYPTO_3DES_CBC: 35512798Swpaul return ("3DES-CBC"); 35612798Swpaul case CRYPTO_MD5_HMAC: 35712798Swpaul return ("HMAC/MD5"); 35812798Swpaul case CRYPTO_SHA1_HMAC: 35912798Swpaul return ("HMAC/SHA1"); 36012798Swpaul case CRYPTO_RIPEMD160_HMAC: 36112798Swpaul return ("HMAC/RIPEMD160"); 36212798Swpaul case CRYPTO_SHA2_256_HMAC: 36312798Swpaul return ("HMAC/SHA256"); 36412798Swpaul case CRYPTO_SHA2_384_HMAC: 36512798Swpaul return ("HMAC/SHA384"); 36612798Swpaul case CRYPTO_SHA2_512_HMAC: 36712798Swpaul return ("HMAC/SHA512"); 36812798Swpaul } 3691897Swollman return ("unknown"); 3701897Swollman} 371152398Sdwmalone 372152398Sdwmalonestatic __inline void 3731897Swollmaneli_metadata_dump(const struct g_eli_metadata *md) 3741897Swollman{ 3751897Swollman static const char hex[] = "0123456789abcdef"; 3761897Swollman char str[sizeof(md->md_mkeys) * 2 + 1]; 3771897Swollman u_int i; 3781897Swollman 3791897Swollman printf(" magic: %s\n", md->md_magic); 38017142Sjkh printf(" version: %u\n", (u_int)md->md_version); 381152398Sdwmalone printf(" flags: 0x%x\n", (u_int)md->md_flags); 3821897Swollman printf(" ealgo: %s\n", g_eli_algo2str(md->md_ealgo)); 3831897Swollman printf(" keylen: %u\n", (u_int)md->md_keylen); 3841897Swollman if (md->md_flags & G_ELI_FLAG_AUTH) 3851897Swollman printf(" aalgo: %s\n", g_eli_algo2str(md->md_aalgo)); 3861897Swollman printf(" provsize: %ju\n", (uintmax_t)md->md_provsize); 3871897Swollman printf("sectorsize: %u\n", (u_int)md->md_sectorsize); 3881897Swollman printf(" keys: 0x%02x\n", (u_int)md->md_keys); 38917142Sjkh printf("iterations: %u\n", (u_int)md->md_iterations); 3901897Swollman bzero(str, sizeof(str)); 3911897Swollman for (i = 0; i < sizeof(md->md_salt); i++) { 3921897Swollman str[i * 2] = hex[md->md_salt[i] >> 4]; 3931897Swollman str[i * 2 + 1] = hex[md->md_salt[i] & 0x0f]; 3941897Swollman } 3951897Swollman printf(" Salt: %s\n", str); 3961897Swollman bzero(str, sizeof(str)); 3971897Swollman for (i = 0; i < sizeof(md->md_mkeys); i++) { 3981897Swollman str[i * 2] = hex[md->md_mkeys[i] >> 4]; 3991897Swollman str[i * 2 + 1] = hex[md->md_mkeys[i] & 0x0f]; 4001897Swollman } 4011897Swollman printf("Master Key: %s\n", str); 40217142Sjkh bzero(str, sizeof(str)); 403152398Sdwmalone for (i = 0; i < 16; i++) { 4041897Swollman str[i * 2] = hex[md->md_hash[i] >> 4]; 4051897Swollman str[i * 2 + 1] = hex[md->md_hash[i] & 0x0f]; 4061897Swollman } 4071897Swollman printf(" MD5 hash: %s\n", str); 4081897Swollman} 4091897Swollman 4101897Swollmanstatic __inline u_int 4111897Swollmang_eli_keylen(u_int algo, u_int keylen) 4121897Swollman{ 4131897Swollman 4141897Swollman switch (algo) { 4151897Swollman case CRYPTO_NULL_CBC: 4161897Swollman if (keylen == 0) 4171897Swollman keylen = 64 * 8; 4181897Swollman else { 4191897Swollman if (keylen > 64 * 8) 4201897Swollman keylen = 0; 4211897Swollman } 4221897Swollman return (keylen); 42312798Swpaul case CRYPTO_AES_CBC: 42412798Swpaul case CRYPTO_CAMELLIA_CBC: 425152398Sdwmalone switch (keylen) { 42612798Swpaul case 0: 42712798Swpaul return (128); 42812798Swpaul case 128: 429100441Scharnier case 192: 43012798Swpaul case 256: 43112798Swpaul return (keylen); 43212798Swpaul default: 43312798Swpaul return (0); 43412798Swpaul } 43512798Swpaul case CRYPTO_AES_XTS: 43612798Swpaul switch (keylen) { 43717142Sjkh case 0: 438152398Sdwmalone return (128); 43912798Swpaul case 128: 44012798Swpaul case 256: 44112798Swpaul return (keylen); 442100441Scharnier default: 44312798Swpaul return (0); 44412798Swpaul } 44512798Swpaul case CRYPTO_BLF_CBC: 44612798Swpaul if (keylen == 0) 44712798Swpaul return (128); 44812798Swpaul if (keylen < 128 || keylen > 448) 44912798Swpaul return (0); 45012798Swpaul if ((keylen % 32) != 0) 45112798Swpaul return (0); 45212798Swpaul return (keylen); 45312798Swpaul case CRYPTO_3DES_CBC: 45412798Swpaul if (keylen == 0 || keylen == 192) 45512798Swpaul return (192); 45612798Swpaul return (0); 45712798Swpaul default: 45812798Swpaul return (0); 45912798Swpaul } 46012798Swpaul} 461152398Sdwmalone 462152398Sdwmalonestatic __inline u_int 46312798Swpaulg_eli_hashlen(u_int algo) 46412798Swpaul{ 46512798Swpaul 46612798Swpaul switch (algo) { 46712798Swpaul case CRYPTO_MD5_HMAC: 46812798Swpaul return (16); 46912798Swpaul case CRYPTO_SHA1_HMAC: 47012798Swpaul return (20); 47112798Swpaul case CRYPTO_RIPEMD160_HMAC: 47212798Swpaul return (20); 47312798Swpaul case CRYPTO_SHA2_256_HMAC: 47412798Swpaul return (32); 47512798Swpaul case CRYPTO_SHA2_384_HMAC: 476100441Scharnier return (48); 477100441Scharnier case CRYPTO_SHA2_512_HMAC: 478100441Scharnier return (64); 479100441Scharnier } 480100441Scharnier return (0); 481100441Scharnier} 482100441Scharnier 483100441Scharnier#ifdef _KERNEL 484100441Scharnierint g_eli_read_metadata(struct g_class *mp, struct g_provider *pp, 485100441Scharnier struct g_eli_metadata *md); 486100441Scharnierstruct g_geom *g_eli_create(struct gctl_req *req, struct g_class *mp, 487100441Scharnier struct g_provider *bpp, const struct g_eli_metadata *md, 488100441Scharnier const u_char *mkey, int nkey); 489100441Scharnierint g_eli_destroy(struct g_eli_softc *sc, boolean_t force); 490100441Scharnier 491100441Scharnierint g_eli_access(struct g_provider *pp, int dr, int dw, int de); 492100441Scharniervoid g_eli_config(struct gctl_req *req, struct g_class *mp, const char *verb); 493100441Scharnier 494100441Scharniervoid g_eli_read_done(struct bio *bp); 495100441Scharniervoid g_eli_write_done(struct bio *bp); 496100441Scharnierint g_eli_crypto_rerun(struct cryptop *crp); 497100441Scharnieruint8_t *g_eli_crypto_key(struct g_eli_softc *sc, off_t offset, 498100441Scharnier size_t blocksize); 499100441Scharniervoid g_eli_crypto_ivgen(struct g_eli_softc *sc, off_t offset, u_char *iv, 500100441Scharnier size_t size); 501100441Scharnier 502100441Scharniervoid g_eli_crypto_run(struct g_eli_worker *wr, struct bio *bp); 503100441Scharnier 504100441Scharniervoid g_eli_auth_read(struct g_eli_softc *sc, struct bio *bp); 505100441Scharniervoid g_eli_auth_run(struct g_eli_worker *wr, struct bio *bp); 506100441Scharnier#endif 507100441Scharnier 508100441Scharniervoid g_eli_mkey_hmac(unsigned char *mkey, const unsigned char *key); 509100441Scharnierint g_eli_mkey_decrypt(const struct g_eli_metadata *md, 510100441Scharnier const unsigned char *key, unsigned char *mkey, unsigned *nkeyp); 511100441Scharnierint g_eli_mkey_encrypt(unsigned algo, const unsigned char *key, unsigned keylen, 512 unsigned char *mkey); 513#ifdef _KERNEL 514void g_eli_mkey_propagate(struct g_eli_softc *sc, const unsigned char *mkey); 515#endif 516 517int g_eli_crypto_encrypt(u_int algo, u_char *data, size_t datasize, 518 const u_char *key, size_t keysize); 519int g_eli_crypto_decrypt(u_int algo, u_char *data, size_t datasize, 520 const u_char *key, size_t keysize); 521 522struct hmac_ctx { 523 SHA512_CTX shactx; 524 u_char k_opad[128]; 525}; 526 527void g_eli_crypto_hmac_init(struct hmac_ctx *ctx, const uint8_t *hkey, 528 size_t hkeylen); 529void g_eli_crypto_hmac_update(struct hmac_ctx *ctx, const uint8_t *data, 530 size_t datasize); 531void g_eli_crypto_hmac_final(struct hmac_ctx *ctx, uint8_t *md, size_t mdsize); 532void g_eli_crypto_hmac(const uint8_t *hkey, size_t hkeysize, 533 const uint8_t *data, size_t datasize, uint8_t *md, size_t mdsize); 534#endif /* !_G_ELI_H_ */ 535