1 /*- 2 * Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org> 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 <geom/geom.h> 41 #else 42 #include <stdio.h> 43 #include <string.h> 44 #include <strings.h> 45 #endif 46 #ifndef _OpenSSL_ 47 #include <sys/md5.h> 48 #endif 49 50 #define G_ELI_CLASS_NAME "ELI" 51 #define G_ELI_MAGIC "GEOM::ELI" 52 #define G_ELI_SUFFIX ".eli" 53 54 /* 55 * Version history: 56 * 0 - Initial version number. 57 */ 58 #define G_ELI_VERSION 0 59 60 /* Use random, onetime keys. */ 61 #define G_ELI_FLAG_ONETIME 0x00000001 62 /* Ask for the passphrase from the kernel, before mounting root. */ 63 #define G_ELI_FLAG_BOOT 0x00000002 64 /* Detach on last close, if we were open for writing. */ 65 #define G_ELI_FLAG_WO_DETACH 0x00000004 66 /* Detach on last close. */ 67 #define G_ELI_FLAG_RW_DETACH 0x00000008 68 /* Provider was open for writing. */ 69 #define G_ELI_FLAG_WOPEN 0x00010000 70 /* Destroy device. */ 71 #define G_ELI_FLAG_DESTROY 0x00020000 72 73 #define SHA512_MDLEN 64 74 75 #define G_ELI_MAXMKEYS 2 76 #define G_ELI_MAXKEYLEN 64 77 #define G_ELI_USERKEYLEN G_ELI_MAXKEYLEN 78 #define G_ELI_DATAKEYLEN G_ELI_MAXKEYLEN 79 #define G_ELI_IVKEYLEN G_ELI_MAXKEYLEN 80 #define G_ELI_SALTLEN 64 81 #define G_ELI_DATAIVKEYLEN (G_ELI_DATAKEYLEN + G_ELI_IVKEYLEN) 82 /* Data-Key, IV-Key, HMAC_SHA512(Derived-Key, Data-Key+IV-Key) */ 83 #define G_ELI_MKEYLEN (G_ELI_DATAIVKEYLEN + SHA512_MDLEN) 84 85 #ifdef _KERNEL 86 extern u_int g_eli_debug; 87 extern u_int g_eli_overwrites; 88 89 #define G_ELI_CRYPTO_HW 1 90 #define G_ELI_CRYPTO_SW 2 91 92 #define G_ELI_DEBUG(lvl, ...) do { \ 93 if (g_eli_debug >= (lvl)) { \ 94 printf("GEOM_ELI"); \ 95 if (g_eli_debug > 0) \ 96 printf("[%u]", lvl); \ 97 printf(": "); \ 98 printf(__VA_ARGS__); \ 99 printf("\n"); \ 100 } \ 101 } while (0) 102 #define G_ELI_LOGREQ(lvl, bp, ...) do { \ 103 if (g_eli_debug >= (lvl)) { \ 104 printf("GEOM_ELI"); \ 105 if (g_eli_debug > 0) \ 106 printf("[%u]", lvl); \ 107 printf(": "); \ 108 printf(__VA_ARGS__); \ 109 printf(" "); \ 110 g_print_bio(bp); \ 111 printf("\n"); \ 112 } \ 113 } while (0) 114 115 struct g_eli_worker { 116 struct g_eli_softc *w_softc; 117 struct proc *w_proc; 118 u_int w_number; 119 uint64_t w_sid; 120 LIST_ENTRY(g_eli_worker) w_next; 121 }; 122 123 struct g_eli_softc { 124 struct g_geom *sc_geom; 125 u_int sc_crypto; 126 uint8_t sc_datakey[G_ELI_DATAKEYLEN]; 127 uint8_t sc_ivkey[G_ELI_IVKEYLEN]; 128 SHA256_CTX sc_ivctx; 129 u_int sc_algo; 130 u_int sc_keylen; 131 int sc_nkey; 132 uint32_t sc_flags; 133 134 /* Only for software cryptography. */ 135 struct bio_queue_head sc_queue; 136 struct mtx sc_queue_mtx; 137 LIST_HEAD(, g_eli_worker) sc_workers; 138 }; 139 #define sc_name sc_geom->name 140 #endif /* _KERNEL */ 141 142 struct g_eli_metadata { 143 char md_magic[16]; /* Magic value. */ 144 uint32_t md_version; /* Version number. */ 145 uint32_t md_flags; /* Additional flags. */ 146 uint16_t md_algo; /* Encryption algorithm. */ 147 uint16_t md_keylen; /* Key length. */ 148 uint64_t md_provsize; /* Provider's size. */ 149 uint32_t md_sectorsize; /* Sector size. */ 150 uint8_t md_keys; /* Available keys. */ 151 int32_t md_iterations; /* Number of iterations for PKCS#5v2. */ 152 uint8_t md_salt[G_ELI_SALTLEN]; /* Salt. */ 153 /* Encrypted master key (IV-key, Data-key, HMAC). */ 154 uint8_t md_mkeys[G_ELI_MAXMKEYS * G_ELI_MKEYLEN]; 155 u_char md_hash[16]; /* MD5 hash. */ 156 } __packed; 157 #ifndef _OpenSSL_ 158 static __inline void 159 eli_metadata_encode(struct g_eli_metadata *md, u_char *data) 160 { 161 MD5_CTX ctx; 162 u_char *p; 163 164 p = data; 165 bcopy(md->md_magic, p, sizeof(md->md_magic)); p += sizeof(md->md_magic); 166 le32enc(p, md->md_version); p += sizeof(md->md_version); 167 le32enc(p, md->md_flags); p += sizeof(md->md_flags); 168 le16enc(p, md->md_algo); p += sizeof(md->md_algo); 169 le16enc(p, md->md_keylen); p += sizeof(md->md_keylen); 170 le64enc(p, md->md_provsize); p += sizeof(md->md_provsize); 171 le32enc(p, md->md_sectorsize); p += sizeof(md->md_sectorsize); 172 *p = md->md_keys; p += sizeof(md->md_keys); 173 le32enc(p, md->md_iterations); p += sizeof(md->md_iterations); 174 bcopy(md->md_salt, p, sizeof(md->md_salt)); p += sizeof(md->md_salt); 175 bcopy(md->md_mkeys, p, sizeof(md->md_mkeys)); p += sizeof(md->md_mkeys); 176 MD5Init(&ctx); 177 MD5Update(&ctx, data, p - data); 178 MD5Final(md->md_hash, &ctx); 179 bcopy(md->md_hash, p, sizeof(md->md_hash)); 180 } 181 static __inline int 182 eli_metadata_decode_v0(const u_char *data, struct g_eli_metadata *md) 183 { 184 MD5_CTX ctx; 185 const u_char *p; 186 187 p = data + sizeof(md->md_magic) + sizeof(md->md_version); 188 md->md_flags = le32dec(p); p += sizeof(md->md_flags); 189 md->md_algo = le16dec(p); p += sizeof(md->md_algo); 190 md->md_keylen = le16dec(p); p += sizeof(md->md_keylen); 191 md->md_provsize = le64dec(p); p += sizeof(md->md_provsize); 192 md->md_sectorsize = le32dec(p); p += sizeof(md->md_sectorsize); 193 md->md_keys = *p; p += sizeof(md->md_keys); 194 md->md_iterations = le32dec(p); p += sizeof(md->md_iterations); 195 bcopy(p, md->md_salt, sizeof(md->md_salt)); p += sizeof(md->md_salt); 196 bcopy(p, md->md_mkeys, sizeof(md->md_mkeys)); p += sizeof(md->md_mkeys); 197 MD5Init(&ctx); 198 MD5Update(&ctx, data, p - data); 199 MD5Final(md->md_hash, &ctx); 200 if (bcmp(md->md_hash, p, 16) != 0) 201 return (EINVAL); 202 return (0); 203 } 204 static __inline int 205 eli_metadata_decode(const u_char *data, struct g_eli_metadata *md) 206 { 207 int error; 208 209 bcopy(data, md->md_magic, sizeof(md->md_magic)); 210 md->md_version = le32dec(data + sizeof(md->md_magic)); 211 switch (md->md_version) { 212 case 0: 213 error = eli_metadata_decode_v0(data, md); 214 break; 215 default: 216 error = EINVAL; 217 break; 218 } 219 return (error); 220 } 221 #endif /* !_OpenSSL */ 222 223 static __inline u_int 224 g_eli_str2algo(const char *name) 225 { 226 227 if (strcasecmp("null", name) == 0) 228 return (CRYPTO_NULL_CBC); 229 else if (strcasecmp("aes", name) == 0) 230 return (CRYPTO_AES_CBC); 231 else if (strcasecmp("blowfish", name) == 0) 232 return (CRYPTO_BLF_CBC); 233 else if (strcasecmp("3des", name) == 0) 234 return (CRYPTO_3DES_CBC); 235 return (CRYPTO_ALGORITHM_MIN - 1); 236 } 237 238 static __inline const char * 239 g_eli_algo2str(u_int algo) 240 { 241 242 switch (algo) { 243 case CRYPTO_NULL_CBC: 244 return ("NULL"); 245 case CRYPTO_AES_CBC: 246 return ("AES"); 247 case CRYPTO_BLF_CBC: 248 return ("Blowfish"); 249 case CRYPTO_3DES_CBC: 250 return ("3DES"); 251 } 252 return ("unknown"); 253 } 254 255 static __inline void 256 eli_metadata_dump(const struct g_eli_metadata *md) 257 { 258 static const char hex[] = "0123456789abcdef"; 259 char str[sizeof(md->md_mkeys) * 2 + 1]; 260 u_int i; 261 262 printf(" magic: %s\n", md->md_magic); 263 printf(" version: %u\n", (u_int)md->md_version); 264 printf(" flags: 0x%x\n", (u_int)md->md_flags); 265 printf(" algo: %s\n", g_eli_algo2str(md->md_algo)); 266 printf(" keylen: %u\n", (u_int)md->md_keylen); 267 printf(" provsize: %ju\n", (uintmax_t)md->md_provsize); 268 printf("sectorsize: %u\n", (u_int)md->md_sectorsize); 269 printf(" keys: 0x%02x\n", (u_int)md->md_keys); 270 printf("iterations: %u\n", (u_int)md->md_iterations); 271 bzero(str, sizeof(str)); 272 for (i = 0; i < sizeof(md->md_salt); i++) { 273 str[i * 2] = hex[md->md_salt[i] >> 4]; 274 str[i * 2 + 1] = hex[md->md_salt[i] & 0x0f]; 275 } 276 printf(" Salt: %s\n", str); 277 bzero(str, sizeof(str)); 278 for (i = 0; i < sizeof(md->md_mkeys); i++) { 279 str[i * 2] = hex[md->md_mkeys[i] >> 4]; 280 str[i * 2 + 1] = hex[md->md_mkeys[i] & 0x0f]; 281 } 282 printf("Master Key: %s\n", str); 283 bzero(str, sizeof(str)); 284 for (i = 0; i < 16; i++) { 285 str[i * 2] = hex[md->md_hash[i] >> 4]; 286 str[i * 2 + 1] = hex[md->md_hash[i] & 0x0f]; 287 } 288 printf(" MD5 hash: %s\n", str); 289 } 290 291 static __inline u_int 292 g_eli_keylen(u_int algo, u_int keylen) 293 { 294 295 switch (algo) { 296 case CRYPTO_NULL_CBC: 297 if (keylen == 0) 298 keylen = 64 * 8; 299 else { 300 if (keylen > 64 * 8) 301 keylen = 0; 302 } 303 return (keylen); 304 case CRYPTO_AES_CBC: 305 switch (keylen) { 306 case 0: 307 return (128); 308 case 128: 309 case 192: 310 case 256: 311 return (keylen); 312 default: 313 return (0); 314 } 315 case CRYPTO_BLF_CBC: 316 if (keylen == 0) 317 return (128); 318 if (keylen < 128 || keylen > 448) 319 return (0); 320 if ((keylen % 32) != 0) 321 return (0); 322 return (keylen); 323 case CRYPTO_3DES_CBC: 324 if (keylen == 0 || keylen == 192) 325 return (192); 326 return (0); 327 default: 328 return (0); 329 } 330 } 331 332 #ifdef _KERNEL 333 int g_eli_read_metadata(struct g_class *mp, struct g_provider *pp, 334 struct g_eli_metadata *md); 335 struct g_geom *g_eli_create(struct gctl_req *req, struct g_class *mp, 336 struct g_provider *bpp, const struct g_eli_metadata *md, 337 const u_char *mkey, int nkey); 338 int g_eli_destroy(struct g_eli_softc *sc, boolean_t force); 339 340 int g_eli_access(struct g_provider *pp, int dr, int dw, int de); 341 void g_eli_config(struct gctl_req *req, struct g_class *mp, const char *verb); 342 #endif 343 344 void g_eli_mkey_hmac(unsigned char *mkey, const unsigned char *key); 345 int g_eli_mkey_decrypt(const struct g_eli_metadata *md, 346 const unsigned char *key, unsigned char *mkey, unsigned *nkeyp); 347 int g_eli_mkey_encrypt(unsigned algo, const unsigned char *key, unsigned keylen, 348 unsigned char *mkey); 349 350 int g_eli_crypto_encrypt(u_int algo, u_char *data, size_t datasize, 351 const u_char *key, size_t keysize); 352 int g_eli_crypto_decrypt(u_int algo, u_char *data, size_t datasize, 353 const u_char *key, size_t keysize); 354 355 struct hmac_ctx { 356 SHA512_CTX shactx; 357 u_char k_opad[128]; 358 }; 359 360 void g_eli_crypto_hmac_init(struct hmac_ctx *ctx, const uint8_t *hkey, 361 size_t hkeylen); 362 void g_eli_crypto_hmac_update(struct hmac_ctx *ctx, const uint8_t *data, 363 size_t datasize); 364 void g_eli_crypto_hmac_final(struct hmac_ctx *ctx, uint8_t *md, size_t mdsize); 365 void g_eli_crypto_hmac(const uint8_t *hkey, size_t hkeysize, 366 const uint8_t *data, size_t datasize, uint8_t *md, size_t mdsize); 367 #endif /* !_G_ELI_H_ */ 368