zfscrypt.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. /*
  2. * GRUB -- GRand Unified Bootloader
  3. * Copyright (C) 2011 Free Software Foundation, Inc.
  4. *
  5. * GRUB is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * GRUB is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include <grub/err.h>
  19. #include <grub/file.h>
  20. #include <grub/mm.h>
  21. #include <grub/misc.h>
  22. #include <grub/disk.h>
  23. #include <grub/partition.h>
  24. #include <grub/dl.h>
  25. #include <grub/types.h>
  26. #include <grub/zfs/zfs.h>
  27. #include <grub/zfs/zio.h>
  28. #include <grub/zfs/dnode.h>
  29. #include <grub/zfs/uberblock_impl.h>
  30. #include <grub/zfs/vdev_impl.h>
  31. #include <grub/zfs/zio_checksum.h>
  32. #include <grub/zfs/zap_impl.h>
  33. #include <grub/zfs/zap_leaf.h>
  34. #include <grub/zfs/zfs_znode.h>
  35. #include <grub/zfs/dmu.h>
  36. #include <grub/zfs/dmu_objset.h>
  37. #include <grub/zfs/sa_impl.h>
  38. #include <grub/zfs/dsl_dir.h>
  39. #include <grub/zfs/dsl_dataset.h>
  40. #include <grub/crypto.h>
  41. #include <grub/extcmd.h>
  42. #include <grub/i18n.h>
  43. GRUB_MOD_LICENSE ("GPLv3+");
  44. /*
  45. Mostly based on following article:
  46. https://blogs.oracle.com/darren/entry/zfs_encryption_what_is_on
  47. */
  48. enum grub_zfs_algo
  49. {
  50. GRUB_ZFS_ALGO_CCM,
  51. GRUB_ZFS_ALGO_GCM,
  52. };
  53. struct grub_zfs_key
  54. {
  55. grub_uint64_t algo;
  56. grub_uint8_t enc_nonce[13];
  57. grub_uint8_t unused[3];
  58. grub_uint8_t enc_key[48];
  59. grub_uint8_t unknown_purpose_nonce[13];
  60. grub_uint8_t unused2[3];
  61. grub_uint8_t unknown_purpose_key[48];
  62. };
  63. struct grub_zfs_wrap_key
  64. {
  65. struct grub_zfs_wrap_key *next;
  66. grub_size_t keylen;
  67. int is_passphrase;
  68. grub_uint64_t key[0];
  69. };
  70. static struct grub_zfs_wrap_key *zfs_wrap_keys;
  71. grub_err_t
  72. grub_zfs_add_key (grub_uint8_t *key_in,
  73. grub_size_t keylen,
  74. int passphrase)
  75. {
  76. struct grub_zfs_wrap_key *key;
  77. if (!passphrase && keylen > 32)
  78. keylen = 32;
  79. key = grub_malloc (sizeof (*key) + keylen);
  80. if (!key)
  81. return grub_errno;
  82. key->is_passphrase = passphrase;
  83. key->keylen = keylen;
  84. grub_memcpy (key->key, key_in, keylen);
  85. key->next = zfs_wrap_keys;
  86. zfs_wrap_keys = key;
  87. return GRUB_ERR_NONE;
  88. }
  89. static gcry_err_code_t
  90. grub_ccm_decrypt (grub_crypto_cipher_handle_t cipher,
  91. grub_uint8_t *out, const grub_uint8_t *in,
  92. grub_size_t psize,
  93. void *mac_out, const void *nonce,
  94. unsigned l, unsigned m)
  95. {
  96. grub_uint8_t iv[16];
  97. grub_uint8_t mul[16];
  98. grub_uint32_t mac[4];
  99. unsigned i, j;
  100. gcry_err_code_t err;
  101. grub_memcpy (iv + 1, nonce, 15 - l);
  102. iv[0] = (l - 1) | (((m-2) / 2) << 3);
  103. for (j = 0; j < l; j++)
  104. iv[15 - j] = psize >> (8 * j);
  105. err = grub_crypto_ecb_encrypt (cipher, mac, iv, 16);
  106. if (err)
  107. return err;
  108. iv[0] = l - 1;
  109. for (i = 0; i < (psize + 15) / 16; i++)
  110. {
  111. grub_size_t csize;
  112. csize = 16;
  113. if (csize > psize - 16 * i)
  114. csize = psize - 16 * i;
  115. for (j = 0; j < l; j++)
  116. iv[15 - j] = (i + 1) >> (8 * j);
  117. err = grub_crypto_ecb_encrypt (cipher, mul, iv, 16);
  118. if (err)
  119. return err;
  120. grub_crypto_xor (out + 16 * i, in + 16 * i, mul, csize);
  121. grub_crypto_xor (mac, mac, out + 16 * i, csize);
  122. err = grub_crypto_ecb_encrypt (cipher, mac, mac, 16);
  123. if (err)
  124. return err;
  125. }
  126. for (j = 0; j < l; j++)
  127. iv[15 - j] = 0;
  128. err = grub_crypto_ecb_encrypt (cipher, mul, iv, 16);
  129. if (err)
  130. return err;
  131. if (mac_out)
  132. grub_crypto_xor (mac_out, mac, mul, m);
  133. return GPG_ERR_NO_ERROR;
  134. }
  135. static void
  136. grub_gcm_mul_x (grub_uint8_t *a)
  137. {
  138. int i;
  139. int c = 0, d = 0;
  140. for (i = 0; i < 16; i++)
  141. {
  142. c = a[i] & 0x1;
  143. a[i] = (a[i] >> 1) | (d << 7);
  144. d = c;
  145. }
  146. if (d)
  147. a[0] ^= 0xe1;
  148. }
  149. static void
  150. grub_gcm_mul (grub_uint8_t *a, const grub_uint8_t *b)
  151. {
  152. grub_uint8_t res[16], bs[16];
  153. int i;
  154. grub_memcpy (bs, b, 16);
  155. grub_memset (res, 0, 16);
  156. for (i = 0; i < 128; i++)
  157. {
  158. if ((a[i / 8] << (i % 8)) & 0x80)
  159. grub_crypto_xor (res, res, bs, 16);
  160. grub_gcm_mul_x (bs);
  161. }
  162. grub_memcpy (a, res, 16);
  163. }
  164. static gcry_err_code_t
  165. grub_gcm_decrypt (grub_crypto_cipher_handle_t cipher,
  166. grub_uint8_t *out, const grub_uint8_t *in,
  167. grub_size_t psize,
  168. void *mac_out, const void *nonce,
  169. unsigned nonce_len, unsigned m)
  170. {
  171. grub_uint8_t iv[16];
  172. grub_uint8_t mul[16];
  173. grub_uint8_t mac[16], h[16], mac_xor[16];
  174. unsigned i, j;
  175. gcry_err_code_t err;
  176. grub_memset (mac, 0, sizeof (mac));
  177. err = grub_crypto_ecb_encrypt (cipher, h, mac, 16);
  178. if (err)
  179. return err;
  180. if (nonce_len == 12)
  181. {
  182. grub_memcpy (iv, nonce, 12);
  183. iv[12] = 0;
  184. iv[13] = 0;
  185. iv[14] = 0;
  186. iv[15] = 1;
  187. }
  188. else
  189. {
  190. grub_memset (iv, 0, sizeof (iv));
  191. grub_memcpy (iv, nonce, nonce_len);
  192. grub_gcm_mul (iv, h);
  193. iv[15] ^= nonce_len * 8;
  194. grub_gcm_mul (iv, h);
  195. }
  196. err = grub_crypto_ecb_encrypt (cipher, mac_xor, iv, 16);
  197. if (err)
  198. return err;
  199. for (i = 0; i < (psize + 15) / 16; i++)
  200. {
  201. grub_size_t csize;
  202. csize = 16;
  203. if (csize > psize - 16 * i)
  204. csize = psize - 16 * i;
  205. for (j = 0; j < 4; j++)
  206. {
  207. iv[15 - j]++;
  208. if (iv[15 - j] != 0)
  209. break;
  210. }
  211. grub_crypto_xor (mac, mac, in + 16 * i, csize);
  212. grub_gcm_mul (mac, h);
  213. err = grub_crypto_ecb_encrypt (cipher, mul, iv, 16);
  214. if (err)
  215. return err;
  216. grub_crypto_xor (out + 16 * i, in + 16 * i, mul, csize);
  217. }
  218. for (j = 0; j < 8; j++)
  219. mac[15 - j] ^= ((((grub_uint64_t) psize) * 8) >> (8 * j));
  220. grub_gcm_mul (mac, h);
  221. if (mac_out)
  222. grub_crypto_xor (mac_out, mac, mac_xor, m);
  223. return GPG_ERR_NO_ERROR;
  224. }
  225. static gcry_err_code_t
  226. algo_decrypt (grub_crypto_cipher_handle_t cipher, grub_uint64_t algo,
  227. grub_uint8_t *out, const grub_uint8_t *in,
  228. grub_size_t psize,
  229. void *mac_out, const void *nonce,
  230. unsigned l, unsigned m)
  231. {
  232. switch (algo)
  233. {
  234. case 0:
  235. return grub_ccm_decrypt (cipher, out, in, psize,
  236. mac_out, nonce, l, m);
  237. case 1:
  238. return grub_gcm_decrypt (cipher, out, in, psize,
  239. mac_out, nonce,
  240. 15 - l, m);
  241. default:
  242. return GPG_ERR_CIPHER_ALGO;
  243. }
  244. }
  245. static grub_err_t
  246. grub_zfs_decrypt_real (grub_crypto_cipher_handle_t cipher,
  247. grub_uint64_t algo,
  248. void *nonce,
  249. char *buf, grub_size_t size,
  250. const grub_uint32_t *expected_mac,
  251. grub_zfs_endian_t endian)
  252. {
  253. grub_uint32_t mac[4];
  254. unsigned i;
  255. grub_uint32_t sw[4];
  256. gcry_err_code_t err;
  257. grub_memcpy (sw, nonce, 16);
  258. if (endian != GRUB_ZFS_BIG_ENDIAN)
  259. for (i = 0; i < 4; i++)
  260. sw[i] = grub_swap_bytes32 (sw[i]);
  261. if (!cipher)
  262. return grub_error (GRUB_ERR_ACCESS_DENIED,
  263. N_("no decryption key available"));
  264. err = algo_decrypt (cipher, algo,
  265. (grub_uint8_t *) buf,
  266. (grub_uint8_t *) buf,
  267. size, mac,
  268. sw + 1, 3, 12);
  269. if (err)
  270. return grub_crypto_gcry_error (err);
  271. for (i = 0; i < 3; i++)
  272. if (grub_zfs_to_cpu32 (expected_mac[i], endian)
  273. != grub_be_to_cpu32 (mac[i]))
  274. return grub_error (GRUB_ERR_BAD_FS, N_("MAC verification failed"));
  275. return GRUB_ERR_NONE;
  276. }
  277. static grub_crypto_cipher_handle_t
  278. grub_zfs_load_key_real (const struct grub_zfs_key *key,
  279. grub_size_t keysize,
  280. grub_uint64_t salt,
  281. grub_uint64_t algo)
  282. {
  283. unsigned keylen;
  284. struct grub_zfs_wrap_key *wrap_key;
  285. grub_crypto_cipher_handle_t ret = NULL;
  286. if (keysize != sizeof (*key))
  287. {
  288. grub_dprintf ("zfs", "Unexpected key size %" PRIuGRUB_SIZE "\n", keysize);
  289. return 0;
  290. }
  291. if (grub_memcmp (key->enc_key + 32, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16)
  292. == 0)
  293. keylen = 16;
  294. else if (grub_memcmp (key->enc_key + 40, "\0\0\0\0\0\0\0\0", 8) == 0)
  295. keylen = 24;
  296. else
  297. keylen = 32;
  298. for (wrap_key = zfs_wrap_keys; wrap_key; wrap_key = wrap_key->next)
  299. {
  300. grub_crypto_cipher_handle_t cipher;
  301. grub_uint8_t decrypted[32], mac[32], wrap_key_real[32];
  302. gcry_err_code_t err;
  303. cipher = grub_crypto_cipher_open (GRUB_CIPHER_AES);
  304. if (!cipher)
  305. {
  306. grub_errno = GRUB_ERR_NONE;
  307. return 0;
  308. }
  309. grub_memset (wrap_key_real, 0, sizeof (wrap_key_real));
  310. err = 0;
  311. if (!wrap_key->is_passphrase)
  312. grub_memcpy(wrap_key_real, wrap_key->key,
  313. wrap_key->keylen < keylen ? wrap_key->keylen : keylen);
  314. else
  315. err = grub_crypto_pbkdf2 (GRUB_MD_SHA1,
  316. (const grub_uint8_t *) wrap_key->key,
  317. wrap_key->keylen,
  318. (const grub_uint8_t *) &salt, sizeof (salt),
  319. 1000, wrap_key_real, keylen);
  320. if (err)
  321. {
  322. grub_errno = GRUB_ERR_NONE;
  323. grub_crypto_cipher_close (cipher);
  324. continue;
  325. }
  326. err = grub_crypto_cipher_set_key (cipher, wrap_key_real,
  327. keylen);
  328. if (err)
  329. {
  330. grub_errno = GRUB_ERR_NONE;
  331. grub_crypto_cipher_close (cipher);
  332. continue;
  333. }
  334. err = algo_decrypt (cipher, algo, decrypted, key->unknown_purpose_key, 32,
  335. mac, key->unknown_purpose_nonce, 2, 16);
  336. if (err || (grub_crypto_memcmp (mac, key->unknown_purpose_key + 32, 16)
  337. != 0))
  338. {
  339. grub_dprintf ("zfs", "key loading failed\n");
  340. grub_errno = GRUB_ERR_NONE;
  341. grub_crypto_cipher_close (cipher);
  342. continue;
  343. }
  344. err = algo_decrypt (cipher, algo, decrypted, key->enc_key, keylen, mac,
  345. key->enc_nonce, 2, 16);
  346. if (err || grub_crypto_memcmp (mac, key->enc_key + keylen, 16) != 0)
  347. {
  348. grub_dprintf ("zfs", "key loading failed\n");
  349. grub_errno = GRUB_ERR_NONE;
  350. grub_crypto_cipher_close (cipher);
  351. continue;
  352. }
  353. ret = grub_crypto_cipher_open (GRUB_CIPHER_AES);
  354. if (!ret)
  355. {
  356. grub_errno = GRUB_ERR_NONE;
  357. grub_crypto_cipher_close (cipher);
  358. continue;
  359. }
  360. err = grub_crypto_cipher_set_key (ret, decrypted, keylen);
  361. if (err)
  362. {
  363. grub_errno = GRUB_ERR_NONE;
  364. grub_crypto_cipher_close (ret);
  365. grub_crypto_cipher_close (cipher);
  366. continue;
  367. }
  368. grub_crypto_cipher_close (cipher);
  369. return ret;
  370. }
  371. return NULL;
  372. }
  373. static const struct grub_arg_option options[] =
  374. {
  375. {"raw", 'r', 0, N_("Assume input is raw."), 0, 0},
  376. {"hex", 'h', 0, N_("Assume input is hex."), 0, 0},
  377. {"passphrase", 'p', 0, N_("Assume input is passphrase."), 0, 0},
  378. {0, 0, 0, 0, 0, 0}
  379. };
  380. static grub_err_t
  381. grub_cmd_zfs_key (grub_extcmd_context_t ctxt, int argc, char **args)
  382. {
  383. grub_uint8_t buf[1024];
  384. grub_ssize_t real_size;
  385. if (argc > 0)
  386. {
  387. grub_file_t file;
  388. file = grub_file_open (args[0]);
  389. if (!file)
  390. return grub_errno;
  391. real_size = grub_file_read (file, buf, 1024);
  392. if (real_size < 0)
  393. return grub_errno;
  394. }
  395. else
  396. {
  397. grub_xputs (_("Enter ZFS password: "));
  398. if (!grub_password_get ((char *) buf, 1023))
  399. return grub_errno;
  400. real_size = grub_strlen ((char *) buf);
  401. }
  402. if (ctxt->state[1].set)
  403. {
  404. int i;
  405. grub_err_t err;
  406. for (i = 0; i < real_size / 2; i++)
  407. {
  408. char c1 = grub_tolower (buf[2 * i]) - '0';
  409. char c2 = grub_tolower (buf[2 * i + 1]) - '0';
  410. if (c1 > 9)
  411. c1 += '0' - 'a' + 10;
  412. if (c2 > 9)
  413. c2 += '0' - 'a' + 10;
  414. buf[i] = (c1 << 4) | c2;
  415. }
  416. err = grub_zfs_add_key (buf, real_size / 2, 0);
  417. if (err)
  418. return err;
  419. return GRUB_ERR_NONE;
  420. }
  421. return grub_zfs_add_key (buf, real_size,
  422. ctxt->state[2].set
  423. || (argc == 0 && !ctxt->state[0].set
  424. && !ctxt->state[1].set));
  425. }
  426. static grub_extcmd_t cmd_key;
  427. GRUB_MOD_INIT(zfscrypt)
  428. {
  429. grub_zfs_decrypt = grub_zfs_decrypt_real;
  430. grub_zfs_load_key = grub_zfs_load_key_real;
  431. cmd_key = grub_register_extcmd ("zfskey", grub_cmd_zfs_key, 0,
  432. N_("[-h|-p|-r] [FILE]"),
  433. N_("Import ZFS wrapping key stored in FILE."),
  434. options);
  435. }
  436. GRUB_MOD_FINI(zfscrypt)
  437. {
  438. grub_zfs_decrypt = 0;
  439. grub_zfs_load_key = 0;
  440. grub_unregister_extcmd (cmd_key);
  441. }