zfscrypt.c 12 KB

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