crypto_keys.c 18 KB

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