1 #include "bsdtar_platform.h"
2
3 #include <errno.h>
4 #include <stdint.h>
5 #include <stdlib.h>
6
7 #include <openssl/crypto.h>
8 #include <openssl/err.h>
9 #include <openssl/rand.h>
10 #include <openssl/rsa.h>
11
12 #include "crypto_entropy.h"
13 #include "sysendian.h"
14 #include "warnp.h"
15
16 #include "crypto.h"
17 #include "crypto_internal.h"
18
19 static struct {
20 RSA * sign_priv;
21 RSA * sign_pub;
22 RSA * encr_priv;
23 RSA * encr_pub;
24 RSA * root_pub;
25 struct crypto_hmac_key * hmac_file;
26 struct crypto_hmac_key * hmac_file_write;
27 struct crypto_hmac_key * hmac_chunk;
28 struct crypto_hmac_key * hmac_name;
29 struct crypto_hmac_key * hmac_cparams;
30 struct crypto_hmac_key * auth_put;
31 struct crypto_hmac_key * auth_get;
32 struct crypto_hmac_key * auth_delete;
33 } keycache;
34
35 static void crypto_keys_atexit(void);
36
37 /*
38 * External key data format:
39 * 4 byte little-endian integer = length of key data
40 * 1 byte = key type
41 * N bytes = key data, in key-specific format
42 */
43 #define KEYHEADER_OFFSET_LEN 0
44 #define KEYHEADER_OFFSET_TYPE 4
45 #define KEYHEADER_LEN 5
46
47 /* Amount of entropy to use for seeding OpenSSL. */
48 #define RANDBUFLEN 2048
49
50 /**
51 * export_key(key, buf, buflen):
52 * If buf != NULL, export the specified key. Return the key length in bytes.
53 */
54 static uint32_t
export_key(int key,uint8_t * buf,size_t buflen)55 export_key(int key, uint8_t * buf, size_t buflen)
56 {
57 uint32_t len;
58
59 switch (key) {
60 case CRYPTO_KEY_SIGN_PRIV:
61 len = crypto_keys_subr_export_RSA_priv(keycache.sign_priv,
62 buf, buflen);
63 break;
64 case CRYPTO_KEY_SIGN_PUB:
65 len = crypto_keys_subr_export_RSA_pub(keycache.sign_pub, buf,
66 buflen);
67 break;
68 case CRYPTO_KEY_ENCR_PRIV:
69 len = crypto_keys_subr_export_RSA_priv(keycache.encr_priv,
70 buf, buflen);
71 break;
72 case CRYPTO_KEY_ENCR_PUB:
73 len = crypto_keys_subr_export_RSA_pub(keycache.encr_pub, buf,
74 buflen);
75 break;
76 case CRYPTO_KEY_HMAC_FILE:
77 len = crypto_keys_subr_export_HMAC(keycache.hmac_file, buf,
78 buflen);
79 break;
80 case CRYPTO_KEY_HMAC_CHUNK:
81 len = crypto_keys_subr_export_HMAC(keycache.hmac_chunk, buf,
82 buflen);
83 break;
84 case CRYPTO_KEY_HMAC_NAME:
85 len = crypto_keys_subr_export_HMAC(keycache.hmac_name,
86 buf, buflen);
87 break;
88 case CRYPTO_KEY_HMAC_CPARAMS:
89 len = crypto_keys_subr_export_HMAC(keycache.hmac_cparams,
90 buf, buflen);
91 break;
92 case CRYPTO_KEY_AUTH_PUT:
93 len = crypto_keys_subr_export_HMAC(keycache.auth_put, buf,
94 buflen);
95 break;
96 case CRYPTO_KEY_AUTH_GET:
97 len = crypto_keys_subr_export_HMAC(keycache.auth_get, buf,
98 buflen);
99 break;
100 case CRYPTO_KEY_AUTH_DELETE:
101 len = crypto_keys_subr_export_HMAC(keycache.auth_delete, buf,
102 buflen);
103 break;
104 default:
105 warn0("Unrecognized key type: %d", key);
106 goto err0;
107 }
108
109 /* Did the key export fail? */
110 if (len == (uint32_t)(-1))
111 goto err0;
112
113 /* Success! */
114 return (len);
115
116 err0:
117 /* Failure! */
118 return ((uint32_t)(-1));
119 }
120
121 /**
122 * crypto_keys_init(void):
123 * Initialize the key cache.
124 */
125 int
crypto_keys_init(void)126 crypto_keys_init(void)
127 {
128 uint8_t randbuf[RANDBUFLEN];
129
130 /*
131 * No keys yet. memset() is insufficient since NULL is not required
132 * to be represented in memory by zeroes.
133 */
134 keycache.sign_priv = NULL;
135 keycache.sign_pub = NULL;
136 keycache.encr_priv = NULL;
137 keycache.encr_pub = NULL;
138 keycache.root_pub = NULL;
139 keycache.hmac_file = NULL;
140 keycache.hmac_file_write = NULL;
141 keycache.hmac_chunk = NULL;
142 keycache.hmac_name = NULL;
143 keycache.hmac_cparams = NULL;
144 keycache.auth_put = NULL;
145 keycache.auth_get = NULL;
146 keycache.auth_delete = NULL;
147
148 /* It's now safe to call crypto_keys_atexit() upon exit. */
149 if (atexit(crypto_keys_atexit)) {
150 warnp("Could not initialize atexit");
151 goto err0;
152 }
153
154 /* Load OpenSSL error strings. */
155 ERR_load_crypto_strings();
156
157 /* Seed OpenSSL entropy pool. */
158 if (crypto_entropy_read(randbuf, RANDBUFLEN)) {
159 warnp("Could not obtain sufficient entropy");
160 goto err0;
161 }
162 RAND_seed(randbuf, RANDBUFLEN);
163
164 /* Load server root public key. */
165 if (crypto_keys_server_import_root()) {
166 warn0("Could not import server root public key");
167 goto err0;
168 }
169
170 /* Initialize keys owned by crypto_file. */
171 if (crypto_file_init_keys()) {
172 warn0("Could not initialize crypto_file keys");
173 goto err0;
174 }
175
176 /* Success! */
177 return (0);
178
179 err0:
180 /* Failure! */
181 return (-1);
182 }
183
184 /**
185 * crypto_keys_atexit(void):
186 * Free the key cache.
187 */
188 static void
crypto_keys_atexit(void)189 crypto_keys_atexit(void)
190 {
191
192 /* Free all RSA keys. */
193 RSA_free(keycache.sign_priv);
194 RSA_free(keycache.sign_pub);
195 RSA_free(keycache.encr_priv);
196 RSA_free(keycache.encr_pub);
197 RSA_free(keycache.root_pub);
198
199 /* Free all HMAC keys. */
200 crypto_keys_subr_free_HMAC(&keycache.hmac_file);
201 crypto_keys_subr_free_HMAC(&keycache.hmac_file_write);
202 crypto_keys_subr_free_HMAC(&keycache.hmac_chunk);
203 crypto_keys_subr_free_HMAC(&keycache.hmac_name);
204 crypto_keys_subr_free_HMAC(&keycache.hmac_cparams);
205 crypto_keys_subr_free_HMAC(&keycache.auth_put);
206 crypto_keys_subr_free_HMAC(&keycache.auth_get);
207 crypto_keys_subr_free_HMAC(&keycache.auth_delete);
208
209 /* Free OpenSSL error strings. */
210 ERR_free_strings();
211
212 /* A more general OpenSSL cleanup function. */
213 CRYPTO_cleanup_all_ex_data();
214 }
215
216 /**
217 * crypto_keys_import(buf, buflen, keys):
218 * Import keys from the provided buffer into the key cache. Ignore any keys
219 * not specified in the mask ${keys}.
220 */
221 int
crypto_keys_import(const uint8_t * buf,size_t buflen,int keys)222 crypto_keys_import(const uint8_t * buf, size_t buflen, int keys)
223 {
224 const uint8_t * kh;
225 uint32_t len;
226 uint8_t type;
227
228 /* Loop until we've processed all the provided data. */
229 while (buflen) {
230 /* We must have at least a key header. */
231 if (buflen < KEYHEADER_LEN) {
232 warn0("Unexpected EOF of key data");
233 goto err0;
234 }
235
236 /* Parse header. */
237 kh = buf;
238 buf += KEYHEADER_LEN;
239 buflen -= KEYHEADER_LEN;
240
241 /* Sanity check length. */
242 len = le32dec(&kh[KEYHEADER_OFFSET_LEN]);
243 if (len > buflen) {
244 warn0("Unexpected EOF of key data");
245 goto err0;
246 }
247
248 /* Parse the key. */
249 type = kh[KEYHEADER_OFFSET_TYPE];
250 switch (type) {
251 case CRYPTO_KEY_SIGN_PRIV:
252 if ((keys & CRYPTO_KEYMASK_SIGN_PRIV) &&
253 crypto_keys_subr_import_RSA_priv(
254 &keycache.sign_priv, buf, len))
255 goto err0;
256 break;
257 case CRYPTO_KEY_SIGN_PUB:
258 if ((keys & CRYPTO_KEYMASK_SIGN_PUB) &&
259 crypto_keys_subr_import_RSA_pub(
260 &keycache.sign_pub, buf, len))
261 goto err0;
262 break;
263 case CRYPTO_KEY_ENCR_PRIV:
264 if ((keys & CRYPTO_KEYMASK_ENCR_PRIV) &&
265 crypto_keys_subr_import_RSA_priv(
266 &keycache.encr_priv, buf, len))
267 goto err0;
268 break;
269 case CRYPTO_KEY_ENCR_PUB:
270 if ((keys & CRYPTO_KEYMASK_ENCR_PUB) &&
271 crypto_keys_subr_import_RSA_pub(
272 &keycache.encr_pub, buf, len))
273 goto err0;
274 break;
275 case CRYPTO_KEY_HMAC_FILE:
276 if ((keys & CRYPTO_KEYMASK_HMAC_FILE) &&
277 crypto_keys_subr_import_HMAC(
278 &keycache.hmac_file, buf, len))
279 goto err0;
280 if ((keys & CRYPTO_KEYMASK_HMAC_FILE_WRITE) &&
281 crypto_keys_subr_import_HMAC(
282 &keycache.hmac_file_write, buf, len))
283 goto err0;
284 break;
285 case CRYPTO_KEY_HMAC_CHUNK:
286 if ((keys & CRYPTO_KEYMASK_HMAC_CHUNK) &&
287 crypto_keys_subr_import_HMAC(
288 &keycache.hmac_chunk, buf, len))
289 goto err0;
290 break;
291 case CRYPTO_KEY_HMAC_NAME:
292 if ((keys & CRYPTO_KEYMASK_HMAC_NAME) &&
293 crypto_keys_subr_import_HMAC(
294 &keycache.hmac_name, buf, len))
295 goto err0;
296 break;
297 case CRYPTO_KEY_HMAC_CPARAMS:
298 if ((keys & CRYPTO_KEYMASK_HMAC_CPARAMS) &&
299 crypto_keys_subr_import_HMAC(
300 &keycache.hmac_cparams, buf, len))
301 goto err0;
302 break;
303 case CRYPTO_KEY_ROOT_PUB:
304 if ((keys & CRYPTO_KEYMASK_ROOT_PUB) &&
305 crypto_keys_subr_import_RSA_pub(
306 &keycache.root_pub, buf, len))
307 goto err0;
308 break;
309 case CRYPTO_KEY_AUTH_PUT:
310 if ((keys & CRYPTO_KEYMASK_AUTH_PUT) &&
311 crypto_keys_subr_import_HMAC(
312 &keycache.auth_put, buf, len))
313 goto err0;
314 break;
315 case CRYPTO_KEY_AUTH_GET:
316 if ((keys & CRYPTO_KEYMASK_AUTH_GET) &&
317 crypto_keys_subr_import_HMAC(
318 &keycache.auth_get, buf, len))
319 goto err0;
320 break;
321 case CRYPTO_KEY_AUTH_DELETE:
322 if ((keys & CRYPTO_KEYMASK_AUTH_DELETE) &&
323 crypto_keys_subr_import_HMAC(
324 &keycache.auth_delete, buf, len))
325 goto err0;
326 break;
327 default:
328 warn0("Unrecognized key type: %d", type);
329 goto err0;
330 }
331
332 /* Move on to the next key. */
333 buf += len;
334 buflen -= len;
335 }
336
337 /* Success! */
338 return (0);
339
340 err0:
341 /* Failure! */
342 return (-1);
343 }
344
345 /**
346 * crypto_keys_missing(keys):
347 * Look for the specified keys. If they are all present, return NULL; if
348 * not, return a pointer to the name of one of the keys.
349 */
350 const char *
crypto_keys_missing(int keys)351 crypto_keys_missing(int keys)
352 {
353 const char * keyname = NULL;
354 int key;
355
356 /*
357 * Go through all the keys we know about and determine if (a) the key
358 * is in the provided mask; and (b) if we do not have it.
359 */
360 for (key = 0; key < (int)(sizeof(int) * 8); key++)
361 if ((keys >> key) & 1) {
362 switch (key) {
363 case CRYPTO_KEY_SIGN_PRIV:
364 if (keycache.sign_priv == NULL)
365 keyname = "archive signing";
366 break;
367 case CRYPTO_KEY_SIGN_PUB:
368 if (keycache.sign_pub == NULL)
369 keyname = "archive signature verification";
370 break;
371 case CRYPTO_KEY_ENCR_PRIV:
372 if (keycache.encr_priv == NULL)
373 keyname = "archive decryption";
374 break;
375 case CRYPTO_KEY_ENCR_PUB:
376 if (keycache.encr_pub == NULL)
377 keyname = "archive encryption";
378 break;
379 case CRYPTO_KEY_HMAC_FILE:
380 if (keycache.hmac_file == NULL)
381 keyname = "file HMAC";
382 break;
383 case CRYPTO_KEY_HMAC_FILE_WRITE:
384 if (keycache.hmac_file_write == NULL)
385 keyname = "file write HMAC";
386 break;
387 case CRYPTO_KEY_HMAC_CHUNK:
388 if (keycache.hmac_chunk == NULL)
389 keyname = "chunk HMAC";
390 break;
391 case CRYPTO_KEY_HMAC_NAME:
392 if (keycache.hmac_name == NULL)
393 keyname = "archive name HMAC";
394 break;
395 case CRYPTO_KEY_HMAC_CPARAMS:
396 if (keycache.hmac_cparams == NULL)
397 keyname = "chunk randomization";
398 break;
399 case CRYPTO_KEY_ROOT_PUB:
400 if (keycache.root_pub == NULL)
401 keyname = "server root";
402 break;
403 case CRYPTO_KEY_AUTH_PUT:
404 if (keycache.auth_put == NULL)
405 keyname = "write authorization";
406 break;
407 case CRYPTO_KEY_AUTH_GET:
408 if (keycache.auth_get == NULL)
409 keyname = "read authorization";
410 break;
411 case CRYPTO_KEY_AUTH_DELETE:
412 if (keycache.auth_delete == NULL)
413 keyname = "delete authorization";
414 break;
415 }
416 }
417
418 /* Return the key name or NULL if we have everything. */
419 return (keyname);
420 }
421
422 /**
423 * crypto_keys_export(keys, buf, buflen):
424 * Export the keys specified to a buffer allocated using malloc.
425 */
426 int
crypto_keys_export(int keys,uint8_t ** buf,size_t * buflen)427 crypto_keys_export(int keys, uint8_t ** buf, size_t * buflen)
428 {
429 uint8_t * kh;
430 size_t bufpos;
431 uint32_t len;
432 int key;
433
434 /* Compute the necessary buffer length. */
435 *buflen = 0;
436 for (key = 0; key < (int)(sizeof(int) * 8); key++)
437 if ((keys >> key) & 1) {
438 /* Determine the length needed for this key. */
439 len = export_key(key, NULL, 0);
440 if (len == (uint32_t)(-1))
441 goto err0;
442
443 /* Add to buffer length, making sure to avoid overflow. */
444 if (*buflen > *buflen + len) {
445 errno = ENOMEM;
446 goto err0;
447 }
448 *buflen += len;
449 if (*buflen > *buflen + KEYHEADER_LEN) {
450 errno = ENOMEM;
451 goto err0;
452 }
453 *buflen += KEYHEADER_LEN;
454 }
455
456 /* Allocate memory. */
457 if ((*buf = malloc(*buflen)) == NULL)
458 goto err0;
459
460 /* Export keys. */
461 bufpos = 0;
462 for (key = 0; key < (int)(sizeof(int) * 8); key++)
463 if ((keys >> key) & 1) {
464 /* Sanity check remaining buffer length. */
465 if (*buflen - bufpos < KEYHEADER_LEN) {
466 warn0("Programmer error");
467 goto err1;
468 }
469
470 /* Export key. */
471 len = export_key(key,
472 *buf + (bufpos + KEYHEADER_LEN),
473 *buflen - (bufpos + KEYHEADER_LEN));
474 if (len == (uint32_t)(-1))
475 goto err1;
476
477 /* Write key header. */
478 kh = *buf + bufpos;
479 le32enc(&kh[KEYHEADER_OFFSET_LEN], len);
480 kh[KEYHEADER_OFFSET_TYPE] = key & 0xff;
481
482 /* Advance buffer position. */
483 bufpos += KEYHEADER_LEN + len;
484 }
485
486 /* Sanity-check -- we should have filled the buffer. */
487 if (bufpos != *buflen) {
488 warn0("Programmer error");
489 goto err1;
490 }
491
492 /* Success! */
493 return (0);
494
495 err1:
496 free(*buf);
497 err0:
498 /* Failure! */
499 return (-1);
500 }
501
502 /**
503 * crypto_keys_generate(keys):
504 * Create the keys specified.
505 */
506 int
crypto_keys_generate(int keys)507 crypto_keys_generate(int keys)
508 {
509
510 /* Archive signing RSA key. */
511 if (keys & CRYPTO_KEYMASK_SIGN_PRIV) {
512 if ((keys & CRYPTO_KEYMASK_SIGN_PUB) == 0) {
513 warn0("Cannot generate %s without %s",
514 "private key", "public key");
515 goto err0;
516 }
517 if (crypto_keys_subr_generate_RSA(&keycache.sign_priv,
518 &keycache.sign_pub))
519 goto err0;
520
521 keys &= ~CRYPTO_KEYMASK_SIGN_PRIV;
522 keys &= ~CRYPTO_KEYMASK_SIGN_PUB;
523 }
524 if (keys & CRYPTO_KEYMASK_SIGN_PUB) {
525 warn0("Cannot generate %s without %s",
526 "public key", "private key");
527 goto err0;
528 }
529
530 /* Encryption RSA key. */
531 if (keys & CRYPTO_KEYMASK_ENCR_PRIV) {
532 if ((keys & CRYPTO_KEYMASK_ENCR_PUB) == 0) {
533 warn0("Cannot generate %s without %s",
534 "private key", "public key");
535 goto err0;
536 }
537 if (crypto_keys_subr_generate_RSA(&keycache.encr_priv,
538 &keycache.encr_pub))
539 goto err0;
540
541 keys &= ~CRYPTO_KEYMASK_ENCR_PRIV;
542 keys &= ~CRYPTO_KEYMASK_ENCR_PUB;
543 }
544 if (keys & CRYPTO_KEYMASK_ENCR_PUB) {
545 warn0("Cannot generate %s without %s",
546 "public key", "private key");
547 goto err0;
548 }
549
550 /* File HMAC key. */
551 if (keys & CRYPTO_KEYMASK_HMAC_FILE) {
552 if (crypto_keys_subr_generate_HMAC(&keycache.hmac_file))
553 goto err0;
554
555 keys &= ~CRYPTO_KEYMASK_HMAC_FILE;
556 }
557
558 /* Chunk HMAC key. */
559 if (keys & CRYPTO_KEYMASK_HMAC_CHUNK) {
560 if (crypto_keys_subr_generate_HMAC(&keycache.hmac_chunk))
561 goto err0;
562
563 keys &= ~CRYPTO_KEYMASK_HMAC_CHUNK;
564 }
565
566 /* Name HMAC key. */
567 if (keys & CRYPTO_KEYMASK_HMAC_NAME) {
568 if (crypto_keys_subr_generate_HMAC(&keycache.hmac_name))
569 goto err0;
570
571 keys &= ~CRYPTO_KEYMASK_HMAC_NAME;
572 }
573
574 /* Chunkification parameters HMAC key. */
575 if (keys & CRYPTO_KEYMASK_HMAC_CPARAMS) {
576 if (crypto_keys_subr_generate_HMAC(&keycache.hmac_cparams))
577 goto err0;
578
579 keys &= ~CRYPTO_KEYMASK_HMAC_CPARAMS;
580 }
581
582 /* Write transaction authorization key. */
583 if (keys & CRYPTO_KEYMASK_AUTH_PUT) {
584 if (crypto_keys_subr_generate_HMAC(&keycache.auth_put))
585 goto err0;
586
587 keys &= ~CRYPTO_KEYMASK_AUTH_PUT;
588 }
589
590 /* Read transaction authorization key. */
591 if (keys & CRYPTO_KEYMASK_AUTH_GET) {
592 if (crypto_keys_subr_generate_HMAC(&keycache.auth_get))
593 goto err0;
594
595 keys &= ~CRYPTO_KEYMASK_AUTH_GET;
596 }
597
598 /* Delete transaction authorization key. */
599 if (keys & CRYPTO_KEYMASK_AUTH_DELETE) {
600 if (crypto_keys_subr_generate_HMAC(&keycache.auth_delete))
601 goto err0;
602
603 keys &= ~CRYPTO_KEYMASK_AUTH_DELETE;
604 }
605
606 /* Anything left? */
607 if (keys) {
608 warn0("Unrecognized key types: %08x", keys);
609 goto err0;
610 }
611
612 /* Success! */
613 return (0);
614
615 err0:
616 /* Failure! */
617 return (-1);
618 }
619
620 /**
621 * crypto_keys_raw_export_auth(buf):
622 * Write into the specified buffer the 32-byte write authorization key,
623 * the 32-byte read authorization key, and the 32-byte delete authorization
624 * key, in that order.
625 */
626 int
crypto_keys_raw_export_auth(uint8_t buf[96])627 crypto_keys_raw_export_auth(uint8_t buf[96])
628 {
629 uint32_t len;
630
631 len = export_key(CRYPTO_KEY_AUTH_PUT, buf, 32);
632 if (len == (uint32_t)(-1))
633 goto err0;
634 if (len != 32) {
635 warn0("Programmer error: "
636 "Incorrect HMAC key size: %u", (unsigned int)len);
637 goto err0;
638 }
639
640 len = export_key(CRYPTO_KEY_AUTH_GET, buf + 32, 32);
641 if (len == (uint32_t)(-1))
642 goto err0;
643 if (len != 32) {
644 warn0("Programmer error: "
645 "Incorrect HMAC key size: %u", (unsigned int)len);
646 goto err0;
647 }
648
649 len = export_key(CRYPTO_KEY_AUTH_DELETE, buf + 64, 32);
650 if (len == (uint32_t)(-1))
651 goto err0;
652 if (len != 32) {
653 warn0("Programmer error: "
654 "Incorrect HMAC key size: %u", (unsigned int)len);
655 goto err0;
656 }
657
658 /* Success! */
659 return (0);
660
661 err0:
662 /* Failure! */
663 return (-1);
664 }
665
666 /**
667 * crypto_keys_lookup_RSA(key):
668 * Return the requested RSA key.
669 */
670 RSA *
crypto_keys_lookup_RSA(int key)671 crypto_keys_lookup_RSA(int key)
672 {
673 RSA * rsa;
674
675 /* Look up the key. */
676 switch (key) {
677 case CRYPTO_KEY_SIGN_PRIV:
678 rsa = keycache.sign_priv;
679 break;
680 case CRYPTO_KEY_SIGN_PUB:
681 rsa = keycache.sign_pub;
682 break;
683 case CRYPTO_KEY_ENCR_PRIV:
684 rsa = keycache.encr_priv;
685 break;
686 case CRYPTO_KEY_ENCR_PUB:
687 rsa = keycache.encr_pub;
688 break;
689 case CRYPTO_KEY_ROOT_PUB:
690 rsa = keycache.root_pub;
691 break;
692 default:
693 warn0("Programmer error: "
694 "invalid key (%d) in crypto_keys_lookup_RSA", key);
695 goto err0;
696 }
697
698 /* Make sure that we have the key. */
699 if (rsa == NULL) {
700 warn0("Programmer error: "
701 "key %d not available in crypto_keys_lookup_RSA", key);
702 goto err0;
703 }
704
705 /* Success! */
706 return (rsa);
707
708 err0:
709 /* Failure! */
710 return (NULL);
711 }
712
713 /**
714 * crypto_keys_lookup_HMAC(key):
715 * Return the requested HMAC key.
716 */
717 struct crypto_hmac_key *
crypto_keys_lookup_HMAC(int key)718 crypto_keys_lookup_HMAC(int key)
719 {
720 struct crypto_hmac_key * hkey;
721
722 /* Look up the key. */
723 switch (key) {
724 case CRYPTO_KEY_HMAC_FILE:
725 hkey = keycache.hmac_file;
726 break;
727 case CRYPTO_KEY_HMAC_FILE_WRITE:
728 hkey = keycache.hmac_file_write;
729 break;
730 case CRYPTO_KEY_HMAC_CHUNK:
731 hkey = keycache.hmac_chunk;
732 break;
733 case CRYPTO_KEY_HMAC_NAME:
734 hkey = keycache.hmac_name;
735 break;
736 case CRYPTO_KEY_HMAC_CPARAMS:
737 hkey = keycache.hmac_cparams;
738 break;
739 case CRYPTO_KEY_AUTH_PUT:
740 hkey = keycache.auth_put;
741 break;
742 case CRYPTO_KEY_AUTH_GET:
743 hkey = keycache.auth_get;
744 break;
745 case CRYPTO_KEY_AUTH_DELETE:
746 hkey = keycache.auth_delete;
747 break;
748 default:
749 warn0("Programmer error: "
750 "invalid key (%d) in crypto_keys_lookup_HMAC", key);
751 goto err0;
752 }
753
754 /* Make sure that we have the key. */
755 if (hkey == NULL) {
756 warn0("Programmer error: "
757 "key %d not available in crypto_keys_lookup_HMAC", key);
758 goto err0;
759 }
760
761 /* Success! */
762 return (hkey);
763
764 err0:
765 /* Failure! */
766 return (NULL);
767 }
768