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