cryptodisk.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332
  1. /*
  2. * GRUB -- GRand Unified Bootloader
  3. * Copyright (C) 2003,2007,2010,2011,2019 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/cryptodisk.h>
  19. #include <grub/mm.h>
  20. #include <grub/misc.h>
  21. #include <grub/dl.h>
  22. #include <grub/extcmd.h>
  23. #include <grub/i18n.h>
  24. #include <grub/fs.h>
  25. #include <grub/file.h>
  26. #include <grub/procfs.h>
  27. #include <grub/partition.h>
  28. #ifdef GRUB_UTIL
  29. #include <grub/emu/hostdisk.h>
  30. #endif
  31. GRUB_MOD_LICENSE ("GPLv3+");
  32. grub_cryptodisk_dev_t grub_cryptodisk_list;
  33. static const struct grub_arg_option options[] =
  34. {
  35. {"uuid", 'u', 0, N_("Mount by UUID."), 0, 0},
  36. /* TRANSLATORS: It's still restricted to cryptodisks only. */
  37. {"all", 'a', 0, N_("Mount all."), 0, 0},
  38. {"boot", 'b', 0, N_("Mount all volumes with `boot' flag set."), 0, 0},
  39. {0, 0, 0, 0, 0, 0}
  40. };
  41. /* Our irreducible polynom is x^128+x^7+x^2+x+1. Lowest byte of it is: */
  42. #define GF_POLYNOM 0x87
  43. static inline int GF_PER_SECTOR (const struct grub_cryptodisk *dev)
  44. {
  45. return 1U << (dev->log_sector_size - GRUB_CRYPTODISK_GF_LOG_BYTES);
  46. }
  47. static grub_cryptodisk_t cryptodisk_list = NULL;
  48. static grub_uint8_t last_cryptodisk_id = 0;
  49. static void
  50. gf_mul_x (grub_uint8_t *g)
  51. {
  52. int over = 0, over2 = 0;
  53. unsigned j;
  54. for (j = 0; j < GRUB_CRYPTODISK_GF_BYTES; j++)
  55. {
  56. over2 = !!(g[j] & 0x80);
  57. g[j] <<= 1;
  58. g[j] |= over;
  59. over = over2;
  60. }
  61. if (over)
  62. g[0] ^= GF_POLYNOM;
  63. }
  64. static void
  65. gf_mul_x_be (grub_uint8_t *g)
  66. {
  67. int over = 0, over2 = 0;
  68. int j;
  69. for (j = (int) GRUB_CRYPTODISK_GF_BYTES - 1; j >= 0; j--)
  70. {
  71. over2 = !!(g[j] & 0x80);
  72. g[j] <<= 1;
  73. g[j] |= over;
  74. over = over2;
  75. }
  76. if (over)
  77. g[GRUB_CRYPTODISK_GF_BYTES - 1] ^= GF_POLYNOM;
  78. }
  79. static void
  80. gf_mul_be (grub_uint8_t *o, const grub_uint8_t *a, const grub_uint8_t *b)
  81. {
  82. unsigned i;
  83. grub_uint8_t t[GRUB_CRYPTODISK_GF_BYTES];
  84. grub_memset (o, 0, GRUB_CRYPTODISK_GF_BYTES);
  85. grub_memcpy (t, b, GRUB_CRYPTODISK_GF_BYTES);
  86. for (i = 0; i < GRUB_CRYPTODISK_GF_SIZE; i++)
  87. {
  88. if (((a[GRUB_CRYPTODISK_GF_BYTES - i / GRUB_CHAR_BIT - 1] >> (i % GRUB_CHAR_BIT))) & 1)
  89. grub_crypto_xor (o, o, t, GRUB_CRYPTODISK_GF_BYTES);
  90. gf_mul_x_be (t);
  91. }
  92. }
  93. static gcry_err_code_t
  94. grub_crypto_pcbc_decrypt (grub_crypto_cipher_handle_t cipher,
  95. void *out, void *in, grub_size_t size,
  96. void *iv)
  97. {
  98. grub_uint8_t *inptr, *outptr, *end;
  99. grub_uint8_t ivt[GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE];
  100. grub_size_t blocksize;
  101. if (!cipher->cipher->decrypt)
  102. return GPG_ERR_NOT_SUPPORTED;
  103. blocksize = cipher->cipher->blocksize;
  104. if (blocksize == 0 || (((blocksize - 1) & blocksize) != 0)
  105. || ((size & (blocksize - 1)) != 0))
  106. return GPG_ERR_INV_ARG;
  107. if (blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE)
  108. return GPG_ERR_INV_ARG;
  109. end = (grub_uint8_t *) in + size;
  110. for (inptr = in, outptr = out; inptr < end;
  111. inptr += blocksize, outptr += blocksize)
  112. {
  113. grub_memcpy (ivt, inptr, blocksize);
  114. cipher->cipher->decrypt (cipher->ctx, outptr, inptr);
  115. grub_crypto_xor (outptr, outptr, iv, blocksize);
  116. grub_crypto_xor (iv, ivt, outptr, blocksize);
  117. }
  118. return GPG_ERR_NO_ERROR;
  119. }
  120. static gcry_err_code_t
  121. grub_crypto_pcbc_encrypt (grub_crypto_cipher_handle_t cipher,
  122. void *out, void *in, grub_size_t size,
  123. void *iv)
  124. {
  125. grub_uint8_t *inptr, *outptr, *end;
  126. grub_uint8_t ivt[GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE];
  127. grub_size_t blocksize;
  128. if (!cipher->cipher->encrypt)
  129. return GPG_ERR_NOT_SUPPORTED;
  130. blocksize = cipher->cipher->blocksize;
  131. if (blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE)
  132. return GPG_ERR_INV_ARG;
  133. if (blocksize == 0 || (((blocksize - 1) & blocksize) != 0)
  134. || ((size & (blocksize - 1)) != 0))
  135. return GPG_ERR_INV_ARG;
  136. end = (grub_uint8_t *) in + size;
  137. for (inptr = in, outptr = out; inptr < end;
  138. inptr += blocksize, outptr += blocksize)
  139. {
  140. grub_memcpy (ivt, inptr, blocksize);
  141. grub_crypto_xor (outptr, outptr, iv, blocksize);
  142. cipher->cipher->encrypt (cipher->ctx, outptr, inptr);
  143. grub_crypto_xor (iv, ivt, outptr, blocksize);
  144. }
  145. return GPG_ERR_NO_ERROR;
  146. }
  147. struct lrw_sector
  148. {
  149. grub_uint8_t low[GRUB_CRYPTODISK_GF_BYTES];
  150. grub_uint8_t high[GRUB_CRYPTODISK_GF_BYTES];
  151. grub_uint8_t low_byte, low_byte_c;
  152. };
  153. static void
  154. generate_lrw_sector (struct lrw_sector *sec,
  155. const struct grub_cryptodisk *dev,
  156. const grub_uint8_t *iv)
  157. {
  158. grub_uint8_t idx[GRUB_CRYPTODISK_GF_BYTES];
  159. grub_uint16_t c;
  160. int j;
  161. grub_memcpy (idx, iv, GRUB_CRYPTODISK_GF_BYTES);
  162. sec->low_byte = (idx[GRUB_CRYPTODISK_GF_BYTES - 1]
  163. & (GF_PER_SECTOR (dev) - 1));
  164. sec->low_byte_c = (((GF_PER_SECTOR (dev) - 1) & ~sec->low_byte) + 1);
  165. idx[GRUB_CRYPTODISK_GF_BYTES - 1] &= ~(GF_PER_SECTOR (dev) - 1);
  166. gf_mul_be (sec->low, dev->lrw_key, idx);
  167. if (!sec->low_byte)
  168. return;
  169. c = idx[GRUB_CRYPTODISK_GF_BYTES - 1] + GF_PER_SECTOR (dev);
  170. if (c & 0x100)
  171. {
  172. for (j = GRUB_CRYPTODISK_GF_BYTES - 2; j >= 0; j--)
  173. {
  174. idx[j]++;
  175. if (idx[j] != 0)
  176. break;
  177. }
  178. }
  179. idx[GRUB_CRYPTODISK_GF_BYTES - 1] = c;
  180. gf_mul_be (sec->high, dev->lrw_key, idx);
  181. }
  182. static void __attribute__ ((unused))
  183. lrw_xor (const struct lrw_sector *sec,
  184. const struct grub_cryptodisk *dev,
  185. grub_uint8_t *b)
  186. {
  187. unsigned i;
  188. for (i = 0; i < sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES;
  189. i += GRUB_CRYPTODISK_GF_BYTES)
  190. grub_crypto_xor (b + i, b + i, sec->low, GRUB_CRYPTODISK_GF_BYTES);
  191. grub_crypto_xor (b, b, dev->lrw_precalc + GRUB_CRYPTODISK_GF_BYTES * sec->low_byte,
  192. sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES);
  193. if (!sec->low_byte)
  194. return;
  195. for (i = sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES;
  196. i < (1U << dev->log_sector_size); i += GRUB_CRYPTODISK_GF_BYTES)
  197. grub_crypto_xor (b + i, b + i, sec->high, GRUB_CRYPTODISK_GF_BYTES);
  198. grub_crypto_xor (b + sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES,
  199. b + sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES,
  200. dev->lrw_precalc, sec->low_byte * GRUB_CRYPTODISK_GF_BYTES);
  201. }
  202. static gcry_err_code_t
  203. grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev,
  204. grub_uint8_t * data, grub_size_t len,
  205. grub_disk_addr_t sector, grub_size_t log_sector_size,
  206. int do_encrypt)
  207. {
  208. grub_size_t i;
  209. gcry_err_code_t err;
  210. if (dev->cipher->cipher->blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE)
  211. return GPG_ERR_INV_ARG;
  212. /* The only mode without IV. */
  213. if (dev->mode == GRUB_CRYPTODISK_MODE_ECB && !dev->rekey)
  214. return (do_encrypt ? grub_crypto_ecb_encrypt (dev->cipher, data, data, len)
  215. : grub_crypto_ecb_decrypt (dev->cipher, data, data, len));
  216. for (i = 0; i < len; i += (1U << log_sector_size))
  217. {
  218. grub_size_t sz = ((dev->cipher->cipher->blocksize
  219. + sizeof (grub_uint32_t) - 1)
  220. / sizeof (grub_uint32_t));
  221. grub_uint32_t iv[(GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE + 3) / 4];
  222. if (dev->rekey)
  223. {
  224. grub_uint64_t zone = sector >> dev->rekey_shift;
  225. if (zone != dev->last_rekey)
  226. {
  227. err = dev->rekey (dev, zone);
  228. if (err)
  229. return err;
  230. dev->last_rekey = zone;
  231. }
  232. }
  233. grub_memset (iv, 0, sizeof (iv));
  234. switch (dev->mode_iv)
  235. {
  236. case GRUB_CRYPTODISK_MODE_IV_NULL:
  237. break;
  238. case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH:
  239. {
  240. grub_uint64_t tmp;
  241. void *ctx;
  242. ctx = grub_zalloc (dev->iv_hash->contextsize);
  243. if (!ctx)
  244. return GPG_ERR_OUT_OF_MEMORY;
  245. tmp = grub_cpu_to_le64 (sector << log_sector_size);
  246. dev->iv_hash->init (ctx);
  247. dev->iv_hash->write (ctx, dev->iv_prefix, dev->iv_prefix_len);
  248. dev->iv_hash->write (ctx, &tmp, sizeof (tmp));
  249. dev->iv_hash->final (ctx);
  250. grub_memcpy (iv, dev->iv_hash->read (ctx), sizeof (iv));
  251. grub_free (ctx);
  252. }
  253. break;
  254. case GRUB_CRYPTODISK_MODE_IV_PLAIN64:
  255. case GRUB_CRYPTODISK_MODE_IV_PLAIN:
  256. /*
  257. * The IV is a 32 or 64 bit value of the dm-crypt native sector
  258. * number. If using 32 bit IV mode, zero out the most significant
  259. * 32 bits.
  260. */
  261. {
  262. grub_uint64_t iv64;
  263. iv64 = grub_cpu_to_le64 (sector << (log_sector_size
  264. - GRUB_CRYPTODISK_IV_LOG_SIZE));
  265. grub_set_unaligned64 (iv, iv64);
  266. if (dev->mode_iv == GRUB_CRYPTODISK_MODE_IV_PLAIN)
  267. iv[1] = 0;
  268. }
  269. break;
  270. case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64:
  271. /* The IV is the 64 bit byte offset of the sector. */
  272. iv[1] = grub_cpu_to_le32 (sector >> (GRUB_TYPE_BITS (iv[1])
  273. - log_sector_size));
  274. iv[0] = grub_cpu_to_le32 ((sector << log_sector_size)
  275. & GRUB_TYPE_U_MAX (iv[0]));
  276. break;
  277. case GRUB_CRYPTODISK_MODE_IV_BENBI:
  278. {
  279. grub_uint64_t num = (sector << dev->benbi_log) + 1;
  280. iv[sz - 2] = grub_cpu_to_be32 (num >> GRUB_TYPE_BITS (iv[0]));
  281. iv[sz - 1] = grub_cpu_to_be32 (num & GRUB_TYPE_U_MAX (iv[0]));
  282. }
  283. break;
  284. case GRUB_CRYPTODISK_MODE_IV_ESSIV:
  285. iv[0] = grub_cpu_to_le32 (sector & GRUB_TYPE_U_MAX (iv[0]));
  286. err = grub_crypto_ecb_encrypt (dev->essiv_cipher, iv, iv,
  287. dev->cipher->cipher->blocksize);
  288. if (err)
  289. return err;
  290. }
  291. switch (dev->mode)
  292. {
  293. case GRUB_CRYPTODISK_MODE_CBC:
  294. if (do_encrypt)
  295. err = grub_crypto_cbc_encrypt (dev->cipher, data + i, data + i,
  296. ((grub_size_t) 1 << log_sector_size), iv);
  297. else
  298. err = grub_crypto_cbc_decrypt (dev->cipher, data + i, data + i,
  299. ((grub_size_t) 1 << log_sector_size), iv);
  300. if (err)
  301. return err;
  302. break;
  303. case GRUB_CRYPTODISK_MODE_PCBC:
  304. if (do_encrypt)
  305. err = grub_crypto_pcbc_encrypt (dev->cipher, data + i, data + i,
  306. ((grub_size_t) 1 << log_sector_size), iv);
  307. else
  308. err = grub_crypto_pcbc_decrypt (dev->cipher, data + i, data + i,
  309. ((grub_size_t) 1 << log_sector_size), iv);
  310. if (err)
  311. return err;
  312. break;
  313. case GRUB_CRYPTODISK_MODE_XTS:
  314. {
  315. unsigned j;
  316. err = grub_crypto_ecb_encrypt (dev->secondary_cipher, iv, iv,
  317. dev->cipher->cipher->blocksize);
  318. if (err)
  319. return err;
  320. for (j = 0; j < (1U << log_sector_size);
  321. j += dev->cipher->cipher->blocksize)
  322. {
  323. grub_crypto_xor (data + i + j, data + i + j, iv,
  324. dev->cipher->cipher->blocksize);
  325. if (do_encrypt)
  326. err = grub_crypto_ecb_encrypt (dev->cipher, data + i + j,
  327. data + i + j,
  328. dev->cipher->cipher->blocksize);
  329. else
  330. err = grub_crypto_ecb_decrypt (dev->cipher, data + i + j,
  331. data + i + j,
  332. dev->cipher->cipher->blocksize);
  333. if (err)
  334. return err;
  335. grub_crypto_xor (data + i + j, data + i + j, iv,
  336. dev->cipher->cipher->blocksize);
  337. gf_mul_x ((grub_uint8_t *) iv);
  338. }
  339. }
  340. break;
  341. case GRUB_CRYPTODISK_MODE_LRW:
  342. {
  343. struct lrw_sector sec;
  344. generate_lrw_sector (&sec, dev, (grub_uint8_t *) iv);
  345. lrw_xor (&sec, dev, data + i);
  346. if (do_encrypt)
  347. err = grub_crypto_ecb_encrypt (dev->cipher, data + i,
  348. data + i,
  349. (1U << log_sector_size));
  350. else
  351. err = grub_crypto_ecb_decrypt (dev->cipher, data + i,
  352. data + i,
  353. (1U << log_sector_size));
  354. if (err)
  355. return err;
  356. lrw_xor (&sec, dev, data + i);
  357. }
  358. break;
  359. case GRUB_CRYPTODISK_MODE_ECB:
  360. if (do_encrypt)
  361. err = grub_crypto_ecb_encrypt (dev->cipher, data + i, data + i,
  362. (1U << log_sector_size));
  363. else
  364. err = grub_crypto_ecb_decrypt (dev->cipher, data + i, data + i,
  365. (1U << log_sector_size));
  366. if (err)
  367. return err;
  368. break;
  369. default:
  370. return GPG_ERR_NOT_IMPLEMENTED;
  371. }
  372. sector++;
  373. }
  374. return GPG_ERR_NO_ERROR;
  375. }
  376. gcry_err_code_t
  377. grub_cryptodisk_decrypt (struct grub_cryptodisk *dev,
  378. grub_uint8_t * data, grub_size_t len,
  379. grub_disk_addr_t sector, grub_size_t log_sector_size)
  380. {
  381. return grub_cryptodisk_endecrypt (dev, data, len, sector, log_sector_size, 0);
  382. }
  383. grub_err_t
  384. grub_cryptodisk_setcipher (grub_cryptodisk_t crypt, const char *ciphername, const char *ciphermode)
  385. {
  386. const char *cipheriv = NULL;
  387. grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL;
  388. grub_crypto_cipher_handle_t essiv_cipher = NULL;
  389. const gcry_md_spec_t *essiv_hash = NULL;
  390. const struct gcry_cipher_spec *ciph;
  391. grub_cryptodisk_mode_t mode;
  392. grub_cryptodisk_mode_iv_t mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64;
  393. int benbi_log = 0;
  394. grub_err_t ret = GRUB_ERR_NONE;
  395. ciph = grub_crypto_lookup_cipher_by_name (ciphername);
  396. if (!ciph)
  397. {
  398. ret = grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s isn't available",
  399. ciphername);
  400. goto err;
  401. }
  402. /* Configure the cipher used for the bulk data. */
  403. cipher = grub_crypto_cipher_open (ciph);
  404. if (!cipher)
  405. {
  406. ret = grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s could not be initialized",
  407. ciphername);
  408. goto err;
  409. }
  410. /* Configure the cipher mode. */
  411. if (grub_strcmp (ciphermode, "ecb") == 0)
  412. {
  413. mode = GRUB_CRYPTODISK_MODE_ECB;
  414. mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
  415. cipheriv = NULL;
  416. }
  417. else if (grub_strcmp (ciphermode, "plain") == 0)
  418. {
  419. mode = GRUB_CRYPTODISK_MODE_CBC;
  420. mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
  421. cipheriv = NULL;
  422. }
  423. else if (grub_memcmp (ciphermode, "cbc-", sizeof ("cbc-") - 1) == 0)
  424. {
  425. mode = GRUB_CRYPTODISK_MODE_CBC;
  426. cipheriv = ciphermode + sizeof ("cbc-") - 1;
  427. }
  428. else if (grub_memcmp (ciphermode, "pcbc-", sizeof ("pcbc-") - 1) == 0)
  429. {
  430. mode = GRUB_CRYPTODISK_MODE_PCBC;
  431. cipheriv = ciphermode + sizeof ("pcbc-") - 1;
  432. }
  433. else if (grub_memcmp (ciphermode, "xts-", sizeof ("xts-") - 1) == 0)
  434. {
  435. mode = GRUB_CRYPTODISK_MODE_XTS;
  436. cipheriv = ciphermode + sizeof ("xts-") - 1;
  437. secondary_cipher = grub_crypto_cipher_open (ciph);
  438. if (!secondary_cipher)
  439. {
  440. ret = grub_error (GRUB_ERR_FILE_NOT_FOUND,
  441. "Secondary cipher %s isn't available", ciphername);
  442. goto err;
  443. }
  444. if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
  445. {
  446. ret = grub_error (GRUB_ERR_BAD_ARGUMENT,
  447. "Unsupported XTS block size: %" PRIuGRUB_SIZE,
  448. cipher->cipher->blocksize);
  449. goto err;
  450. }
  451. if (secondary_cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
  452. {
  453. ret = grub_error (GRUB_ERR_BAD_ARGUMENT,
  454. "Unsupported XTS block size: %" PRIuGRUB_SIZE,
  455. secondary_cipher->cipher->blocksize);
  456. goto err;
  457. }
  458. }
  459. else if (grub_memcmp (ciphermode, "lrw-", sizeof ("lrw-") - 1) == 0)
  460. {
  461. mode = GRUB_CRYPTODISK_MODE_LRW;
  462. cipheriv = ciphermode + sizeof ("lrw-") - 1;
  463. if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
  464. {
  465. ret = grub_error (GRUB_ERR_BAD_ARGUMENT,
  466. "Unsupported LRW block size: %" PRIuGRUB_SIZE,
  467. cipher->cipher->blocksize);
  468. goto err;
  469. }
  470. }
  471. else
  472. {
  473. ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown cipher mode: %s",
  474. ciphermode);
  475. goto err;
  476. }
  477. if (cipheriv == NULL)
  478. ;
  479. else if (grub_memcmp (cipheriv, "plain64", sizeof ("plain64") - 1) == 0)
  480. mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64;
  481. else if (grub_memcmp (cipheriv, "plain", sizeof ("plain") - 1) == 0)
  482. mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
  483. else if (grub_memcmp (cipheriv, "benbi", sizeof ("benbi") - 1) == 0)
  484. {
  485. if (cipher->cipher->blocksize & (cipher->cipher->blocksize - 1)
  486. || cipher->cipher->blocksize == 0)
  487. grub_error (GRUB_ERR_BAD_ARGUMENT,
  488. "Unsupported benbi blocksize: %" PRIuGRUB_SIZE,
  489. cipher->cipher->blocksize);
  490. /* FIXME should we return an error here? */
  491. for (benbi_log = 0;
  492. (cipher->cipher->blocksize << benbi_log) < GRUB_DISK_SECTOR_SIZE;
  493. benbi_log++);
  494. mode_iv = GRUB_CRYPTODISK_MODE_IV_BENBI;
  495. }
  496. else if (grub_memcmp (cipheriv, "null", sizeof ("null") - 1) == 0)
  497. mode_iv = GRUB_CRYPTODISK_MODE_IV_NULL;
  498. else if (grub_memcmp (cipheriv, "essiv:", sizeof ("essiv:") - 1) == 0)
  499. {
  500. const char *hash_str = cipheriv + 6;
  501. mode_iv = GRUB_CRYPTODISK_MODE_IV_ESSIV;
  502. /* Configure the hash and cipher used for ESSIV. */
  503. essiv_hash = grub_crypto_lookup_md_by_name (hash_str);
  504. if (!essiv_hash)
  505. {
  506. ret = grub_error (GRUB_ERR_FILE_NOT_FOUND,
  507. "Couldn't load %s hash", hash_str);
  508. goto err;
  509. }
  510. essiv_cipher = grub_crypto_cipher_open (ciph);
  511. if (!essiv_cipher)
  512. {
  513. ret = grub_error (GRUB_ERR_FILE_NOT_FOUND,
  514. "Couldn't load %s cipher", ciphername);
  515. goto err;
  516. }
  517. }
  518. else
  519. {
  520. ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown IV mode: %s",
  521. cipheriv);
  522. goto err;
  523. }
  524. crypt->cipher = cipher;
  525. crypt->benbi_log = benbi_log;
  526. crypt->mode = mode;
  527. crypt->mode_iv = mode_iv;
  528. crypt->secondary_cipher = secondary_cipher;
  529. crypt->essiv_cipher = essiv_cipher;
  530. crypt->essiv_hash = essiv_hash;
  531. err:
  532. if (ret)
  533. {
  534. grub_crypto_cipher_close (cipher);
  535. grub_crypto_cipher_close (secondary_cipher);
  536. }
  537. return ret;
  538. }
  539. gcry_err_code_t
  540. grub_cryptodisk_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, grub_size_t keysize)
  541. {
  542. gcry_err_code_t err;
  543. int real_keysize;
  544. real_keysize = keysize;
  545. if (dev->mode == GRUB_CRYPTODISK_MODE_XTS)
  546. real_keysize /= 2;
  547. if (dev->mode == GRUB_CRYPTODISK_MODE_LRW)
  548. real_keysize -= dev->cipher->cipher->blocksize;
  549. /* Set the PBKDF2 output as the cipher key. */
  550. err = grub_crypto_cipher_set_key (dev->cipher, key, real_keysize);
  551. if (err)
  552. return err;
  553. grub_memcpy (dev->key, key, keysize);
  554. dev->keysize = keysize;
  555. /* Configure ESSIV if necessary. */
  556. if (dev->mode_iv == GRUB_CRYPTODISK_MODE_IV_ESSIV)
  557. {
  558. grub_size_t essiv_keysize = dev->essiv_hash->mdlen;
  559. grub_uint8_t hashed_key[GRUB_CRYPTO_MAX_MDLEN];
  560. if (essiv_keysize > GRUB_CRYPTO_MAX_MDLEN)
  561. return GPG_ERR_INV_ARG;
  562. grub_crypto_hash (dev->essiv_hash, hashed_key, key, keysize);
  563. err = grub_crypto_cipher_set_key (dev->essiv_cipher,
  564. hashed_key, essiv_keysize);
  565. if (err)
  566. return err;
  567. }
  568. if (dev->mode == GRUB_CRYPTODISK_MODE_XTS)
  569. {
  570. err = grub_crypto_cipher_set_key (dev->secondary_cipher,
  571. key + real_keysize,
  572. keysize / 2);
  573. if (err)
  574. return err;
  575. }
  576. if (dev->mode == GRUB_CRYPTODISK_MODE_LRW)
  577. {
  578. unsigned i;
  579. grub_uint8_t idx[GRUB_CRYPTODISK_GF_BYTES];
  580. grub_free (dev->lrw_precalc);
  581. grub_memcpy (dev->lrw_key, key + real_keysize,
  582. dev->cipher->cipher->blocksize);
  583. dev->lrw_precalc = grub_malloc ((1U << dev->log_sector_size));
  584. if (!dev->lrw_precalc)
  585. return GPG_ERR_OUT_OF_MEMORY;
  586. grub_memset (idx, 0, GRUB_CRYPTODISK_GF_BYTES);
  587. for (i = 0; i < (1U << dev->log_sector_size);
  588. i += GRUB_CRYPTODISK_GF_BYTES)
  589. {
  590. idx[GRUB_CRYPTODISK_GF_BYTES - 1] = i / GRUB_CRYPTODISK_GF_BYTES;
  591. gf_mul_be (dev->lrw_precalc + i, idx, dev->lrw_key);
  592. }
  593. }
  594. return GPG_ERR_NO_ERROR;
  595. }
  596. static int
  597. grub_cryptodisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
  598. grub_disk_pull_t pull)
  599. {
  600. grub_cryptodisk_t i;
  601. if (pull != GRUB_DISK_PULL_NONE)
  602. return 0;
  603. for (i = cryptodisk_list; i != NULL; i = i->next)
  604. {
  605. char buf[30];
  606. grub_snprintf (buf, sizeof (buf), "crypto%lu", i->id);
  607. if (hook (buf, hook_data))
  608. return 1;
  609. }
  610. return GRUB_ERR_NONE;
  611. }
  612. static grub_err_t
  613. grub_cryptodisk_open (const char *name, grub_disk_t disk)
  614. {
  615. grub_cryptodisk_t dev;
  616. if (grub_memcmp (name, "crypto", sizeof ("crypto") - 1) != 0)
  617. return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device");
  618. if (grub_memcmp (name, "cryptouuid/", sizeof ("cryptouuid/") - 1) == 0)
  619. {
  620. for (dev = cryptodisk_list; dev != NULL; dev = dev->next)
  621. if (grub_strcasecmp (name + sizeof ("cryptouuid/") - 1, dev->uuid) == 0)
  622. break;
  623. }
  624. else
  625. {
  626. unsigned long id = grub_strtoul (name + sizeof ("crypto") - 1, 0, 0);
  627. if (grub_errno)
  628. return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device");
  629. /* Search for requested device in the list of CRYPTODISK devices. */
  630. for (dev = cryptodisk_list; dev != NULL; dev = dev->next)
  631. if (dev->id == id)
  632. break;
  633. }
  634. if (!dev)
  635. return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device");
  636. disk->log_sector_size = dev->log_sector_size;
  637. #ifdef GRUB_UTIL
  638. if (dev->cheat)
  639. {
  640. if (!GRUB_UTIL_FD_IS_VALID (dev->cheat_fd))
  641. dev->cheat_fd = grub_util_fd_open (dev->cheat, GRUB_UTIL_FD_O_RDONLY);
  642. if (!GRUB_UTIL_FD_IS_VALID (dev->cheat_fd))
  643. return grub_error (GRUB_ERR_IO, N_("cannot open `%s': %s"),
  644. dev->cheat, grub_util_fd_strerror ());
  645. }
  646. #endif
  647. if (!dev->source_disk)
  648. {
  649. grub_dprintf ("cryptodisk", "Opening device %s\n", name);
  650. /* Try to open the source disk and populate the requested disk. */
  651. dev->source_disk = grub_disk_open (dev->source);
  652. if (!dev->source_disk)
  653. return grub_errno;
  654. }
  655. disk->data = dev;
  656. disk->total_sectors = dev->total_sectors;
  657. disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE;
  658. disk->id = dev->id;
  659. dev->ref++;
  660. return GRUB_ERR_NONE;
  661. }
  662. static void
  663. grub_cryptodisk_close (grub_disk_t disk)
  664. {
  665. grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data;
  666. grub_dprintf ("cryptodisk", "Closing disk\n");
  667. dev->ref--;
  668. if (dev->ref != 0)
  669. return;
  670. #ifdef GRUB_UTIL
  671. if (dev->cheat)
  672. {
  673. grub_util_fd_close (dev->cheat_fd);
  674. dev->cheat_fd = GRUB_UTIL_FD_INVALID;
  675. }
  676. #endif
  677. grub_disk_close (dev->source_disk);
  678. dev->source_disk = NULL;
  679. }
  680. static grub_err_t
  681. grub_cryptodisk_read (grub_disk_t disk, grub_disk_addr_t sector,
  682. grub_size_t size, char *buf)
  683. {
  684. grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data;
  685. grub_err_t err;
  686. gcry_err_code_t gcry_err;
  687. #ifdef GRUB_UTIL
  688. if (dev->cheat)
  689. {
  690. int r;
  691. r = grub_util_fd_seek (dev->cheat_fd, sector << disk->log_sector_size);
  692. if (r)
  693. return grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot seek `%s': %s"),
  694. dev->cheat, grub_util_fd_strerror ());
  695. if (grub_util_fd_read (dev->cheat_fd, buf, size << disk->log_sector_size)
  696. != (ssize_t) (size << disk->log_sector_size))
  697. return grub_error (GRUB_ERR_READ_ERROR, N_("cannot read `%s': %s"),
  698. dev->cheat, grub_util_fd_strerror ());
  699. return GRUB_ERR_NONE;
  700. }
  701. #endif
  702. grub_dprintf ("cryptodisk",
  703. "Reading %" PRIuGRUB_SIZE " sectors from sector 0x%"
  704. PRIxGRUB_UINT64_T " with offset of %" PRIuGRUB_UINT64_T "\n",
  705. size, sector, dev->offset_sectors);
  706. err = grub_disk_read (dev->source_disk,
  707. grub_disk_from_native_sector (disk, sector + dev->offset_sectors),
  708. 0, size << disk->log_sector_size, buf);
  709. if (err)
  710. {
  711. grub_dprintf ("cryptodisk", "grub_disk_read failed with error %d\n", err);
  712. return err;
  713. }
  714. gcry_err = grub_cryptodisk_endecrypt (dev, (grub_uint8_t *) buf,
  715. size << disk->log_sector_size,
  716. sector, dev->log_sector_size, 0);
  717. return grub_crypto_gcry_error (gcry_err);
  718. }
  719. static grub_err_t
  720. grub_cryptodisk_write (grub_disk_t disk, grub_disk_addr_t sector,
  721. grub_size_t size, const char *buf)
  722. {
  723. grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data;
  724. gcry_err_code_t gcry_err;
  725. char *tmp;
  726. grub_err_t err;
  727. #ifdef GRUB_UTIL
  728. if (dev->cheat)
  729. {
  730. int r;
  731. r = grub_util_fd_seek (dev->cheat_fd, sector << disk->log_sector_size);
  732. if (r)
  733. return grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot seek `%s': %s"),
  734. dev->cheat, grub_util_fd_strerror ());
  735. if (grub_util_fd_write (dev->cheat_fd, buf, size << disk->log_sector_size)
  736. != (ssize_t) (size << disk->log_sector_size))
  737. return grub_error (GRUB_ERR_READ_ERROR, N_("cannot read `%s': %s"),
  738. dev->cheat, grub_util_fd_strerror ());
  739. return GRUB_ERR_NONE;
  740. }
  741. #endif
  742. tmp = grub_malloc (size << disk->log_sector_size);
  743. if (!tmp)
  744. return grub_errno;
  745. grub_memcpy (tmp, buf, size << disk->log_sector_size);
  746. grub_dprintf ("cryptodisk",
  747. "Writing %" PRIuGRUB_SIZE " sectors to sector 0x%"
  748. PRIxGRUB_UINT64_T " with offset of %" PRIuGRUB_UINT64_T "\n",
  749. size, sector, dev->offset_sectors);
  750. gcry_err = grub_cryptodisk_endecrypt (dev, (grub_uint8_t *) tmp,
  751. size << disk->log_sector_size,
  752. sector, disk->log_sector_size, 1);
  753. if (gcry_err)
  754. {
  755. grub_free (tmp);
  756. return grub_crypto_gcry_error (gcry_err);
  757. }
  758. /* Since ->write was called so disk.mod is loaded but be paranoid */
  759. sector = sector + dev->offset_sectors;
  760. if (grub_disk_write_weak)
  761. err = grub_disk_write_weak (dev->source_disk,
  762. grub_disk_from_native_sector (disk, sector),
  763. 0, size << disk->log_sector_size, tmp);
  764. else
  765. err = grub_error (GRUB_ERR_BUG, "disk.mod not loaded");
  766. grub_free (tmp);
  767. return err;
  768. }
  769. #ifdef GRUB_UTIL
  770. static grub_disk_memberlist_t
  771. grub_cryptodisk_memberlist (grub_disk_t disk)
  772. {
  773. grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data;
  774. grub_disk_memberlist_t list = NULL;
  775. list = grub_malloc (sizeof (*list));
  776. if (list)
  777. {
  778. list->disk = dev->source_disk;
  779. list->next = NULL;
  780. }
  781. return list;
  782. }
  783. #endif
  784. static void
  785. cryptodisk_cleanup (void)
  786. {
  787. #if 0
  788. grub_cryptodisk_t dev = cryptodisk_list;
  789. grub_cryptodisk_t tmp;
  790. while (dev != NULL)
  791. {
  792. grub_free (dev->source);
  793. grub_free (dev->cipher);
  794. grub_free (dev->secondary_cipher);
  795. grub_free (dev->essiv_cipher);
  796. tmp = dev->next;
  797. grub_free (dev);
  798. dev = tmp;
  799. }
  800. #endif
  801. }
  802. grub_err_t
  803. grub_cryptodisk_insert (grub_cryptodisk_t newdev, const char *name,
  804. grub_disk_t source)
  805. {
  806. newdev->source = grub_strdup (name);
  807. if (!newdev->source)
  808. {
  809. grub_free (newdev);
  810. return grub_errno;
  811. }
  812. newdev->id = last_cryptodisk_id++;
  813. newdev->source_id = source->id;
  814. newdev->source_dev_id = source->dev->id;
  815. newdev->partition_start = grub_partition_get_start (source->partition);
  816. newdev->next = cryptodisk_list;
  817. cryptodisk_list = newdev;
  818. return GRUB_ERR_NONE;
  819. }
  820. grub_cryptodisk_t
  821. grub_cryptodisk_get_by_uuid (const char *uuid)
  822. {
  823. grub_cryptodisk_t dev;
  824. for (dev = cryptodisk_list; dev != NULL; dev = dev->next)
  825. if (grub_strcasecmp (dev->uuid, uuid) == 0)
  826. return dev;
  827. return NULL;
  828. }
  829. grub_cryptodisk_t
  830. grub_cryptodisk_get_by_source_disk (grub_disk_t disk)
  831. {
  832. grub_cryptodisk_t dev;
  833. for (dev = cryptodisk_list; dev != NULL; dev = dev->next)
  834. if (dev->source_id == disk->id && dev->source_dev_id == disk->dev->id)
  835. if ((disk->partition && grub_partition_get_start (disk->partition) == dev->partition_start) ||
  836. (!disk->partition && dev->partition_start == 0))
  837. return dev;
  838. return NULL;
  839. }
  840. #ifdef GRUB_UTIL
  841. grub_err_t
  842. grub_cryptodisk_cheat_insert (grub_cryptodisk_t newdev, const char *name,
  843. grub_disk_t source, const char *cheat)
  844. {
  845. newdev->cheat = grub_strdup (cheat);
  846. newdev->source = grub_strdup (name);
  847. if (!newdev->source || !newdev->cheat)
  848. {
  849. grub_free (newdev->source);
  850. grub_free (newdev->cheat);
  851. return grub_errno;
  852. }
  853. newdev->cheat_fd = GRUB_UTIL_FD_INVALID;
  854. newdev->source_id = source->id;
  855. newdev->source_dev_id = source->dev->id;
  856. newdev->partition_start = grub_partition_get_start (source->partition);
  857. newdev->id = last_cryptodisk_id++;
  858. newdev->next = cryptodisk_list;
  859. cryptodisk_list = newdev;
  860. return GRUB_ERR_NONE;
  861. }
  862. void
  863. grub_util_cryptodisk_get_abstraction (grub_disk_t disk,
  864. void (*cb) (const char *val, void *data),
  865. void *data)
  866. {
  867. grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data;
  868. cb ("cryptodisk", data);
  869. cb (dev->modname, data);
  870. if (dev->cipher)
  871. cb (dev->cipher->cipher->modname, data);
  872. if (dev->secondary_cipher)
  873. cb (dev->secondary_cipher->cipher->modname, data);
  874. if (dev->essiv_cipher)
  875. cb (dev->essiv_cipher->cipher->modname, data);
  876. if (dev->hash)
  877. cb (dev->hash->modname, data);
  878. if (dev->essiv_hash)
  879. cb (dev->essiv_hash->modname, data);
  880. if (dev->iv_hash)
  881. cb (dev->iv_hash->modname, data);
  882. }
  883. const char *
  884. grub_util_cryptodisk_get_uuid (grub_disk_t disk)
  885. {
  886. grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data;
  887. return dev->uuid;
  888. }
  889. #endif
  890. static int check_boot, have_it;
  891. static char *search_uuid;
  892. static void
  893. cryptodisk_close (grub_cryptodisk_t dev)
  894. {
  895. grub_crypto_cipher_close (dev->cipher);
  896. grub_crypto_cipher_close (dev->secondary_cipher);
  897. grub_crypto_cipher_close (dev->essiv_cipher);
  898. grub_free (dev);
  899. }
  900. static grub_err_t
  901. grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source)
  902. {
  903. grub_err_t err;
  904. grub_cryptodisk_t dev;
  905. grub_cryptodisk_dev_t cr;
  906. dev = grub_cryptodisk_get_by_source_disk (source);
  907. if (dev)
  908. return GRUB_ERR_NONE;
  909. FOR_CRYPTODISK_DEVS (cr)
  910. {
  911. dev = cr->scan (source, search_uuid, check_boot);
  912. if (grub_errno)
  913. return grub_errno;
  914. if (!dev)
  915. continue;
  916. err = cr->recover_key (source, dev);
  917. if (err)
  918. {
  919. cryptodisk_close (dev);
  920. return err;
  921. }
  922. grub_cryptodisk_insert (dev, name, source);
  923. have_it = 1;
  924. return GRUB_ERR_NONE;
  925. }
  926. return GRUB_ERR_NONE;
  927. }
  928. #ifdef GRUB_UTIL
  929. #include <grub/util/misc.h>
  930. grub_err_t
  931. grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat)
  932. {
  933. grub_err_t err;
  934. grub_cryptodisk_t dev;
  935. grub_cryptodisk_dev_t cr;
  936. grub_disk_t source;
  937. /* Try to open disk. */
  938. source = grub_disk_open (sourcedev);
  939. if (!source)
  940. return grub_errno;
  941. dev = grub_cryptodisk_get_by_source_disk (source);
  942. if (dev)
  943. {
  944. grub_disk_close (source);
  945. return GRUB_ERR_NONE;
  946. }
  947. FOR_CRYPTODISK_DEVS (cr)
  948. {
  949. dev = cr->scan (source, search_uuid, check_boot);
  950. if (grub_errno)
  951. return grub_errno;
  952. if (!dev)
  953. continue;
  954. grub_util_info ("cheatmounted %s (%s) at %s", sourcedev, dev->modname,
  955. cheat);
  956. err = grub_cryptodisk_cheat_insert (dev, sourcedev, source, cheat);
  957. grub_disk_close (source);
  958. if (err)
  959. grub_free (dev);
  960. return GRUB_ERR_NONE;
  961. }
  962. grub_disk_close (source);
  963. return GRUB_ERR_NONE;
  964. }
  965. #endif
  966. static int
  967. grub_cryptodisk_scan_device (const char *name,
  968. void *data __attribute__ ((unused)))
  969. {
  970. grub_err_t err;
  971. grub_disk_t source;
  972. /* Try to open disk. */
  973. source = grub_disk_open (name);
  974. if (!source)
  975. {
  976. grub_print_error ();
  977. return 0;
  978. }
  979. err = grub_cryptodisk_scan_device_real (name, source);
  980. grub_disk_close (source);
  981. if (err)
  982. grub_print_error ();
  983. return have_it && search_uuid ? 1 : 0;
  984. }
  985. static grub_err_t
  986. grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
  987. {
  988. struct grub_arg_list *state = ctxt->state;
  989. if (argc < 1 && !state[1].set && !state[2].set)
  990. return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
  991. have_it = 0;
  992. if (state[0].set)
  993. {
  994. grub_cryptodisk_t dev;
  995. dev = grub_cryptodisk_get_by_uuid (args[0]);
  996. if (dev)
  997. {
  998. grub_dprintf ("cryptodisk",
  999. "already mounted as crypto%lu\n", dev->id);
  1000. return GRUB_ERR_NONE;
  1001. }
  1002. check_boot = state[2].set;
  1003. search_uuid = args[0];
  1004. grub_device_iterate (&grub_cryptodisk_scan_device, NULL);
  1005. search_uuid = NULL;
  1006. if (!have_it)
  1007. return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found");
  1008. return GRUB_ERR_NONE;
  1009. }
  1010. else if (state[1].set || (argc == 0 && state[2].set))
  1011. {
  1012. search_uuid = NULL;
  1013. check_boot = state[2].set;
  1014. grub_device_iterate (&grub_cryptodisk_scan_device, NULL);
  1015. search_uuid = NULL;
  1016. return GRUB_ERR_NONE;
  1017. }
  1018. else
  1019. {
  1020. grub_err_t err;
  1021. grub_disk_t disk;
  1022. grub_cryptodisk_t dev;
  1023. char *diskname;
  1024. char *disklast = NULL;
  1025. grub_size_t len;
  1026. search_uuid = NULL;
  1027. check_boot = state[2].set;
  1028. diskname = args[0];
  1029. len = grub_strlen (diskname);
  1030. if (len && diskname[0] == '(' && diskname[len - 1] == ')')
  1031. {
  1032. disklast = &diskname[len - 1];
  1033. *disklast = '\0';
  1034. diskname++;
  1035. }
  1036. disk = grub_disk_open (diskname);
  1037. if (!disk)
  1038. {
  1039. if (disklast)
  1040. *disklast = ')';
  1041. return grub_errno;
  1042. }
  1043. dev = grub_cryptodisk_get_by_source_disk (disk);
  1044. if (dev)
  1045. {
  1046. grub_dprintf ("cryptodisk", "already mounted as crypto%lu\n", dev->id);
  1047. grub_disk_close (disk);
  1048. if (disklast)
  1049. *disklast = ')';
  1050. return GRUB_ERR_NONE;
  1051. }
  1052. err = grub_cryptodisk_scan_device_real (diskname, disk);
  1053. grub_disk_close (disk);
  1054. if (disklast)
  1055. *disklast = ')';
  1056. return err;
  1057. }
  1058. }
  1059. static struct grub_disk_dev grub_cryptodisk_dev = {
  1060. .name = "cryptodisk",
  1061. .id = GRUB_DISK_DEVICE_CRYPTODISK_ID,
  1062. .disk_iterate = grub_cryptodisk_iterate,
  1063. .disk_open = grub_cryptodisk_open,
  1064. .disk_close = grub_cryptodisk_close,
  1065. .disk_read = grub_cryptodisk_read,
  1066. .disk_write = grub_cryptodisk_write,
  1067. #ifdef GRUB_UTIL
  1068. .disk_memberlist = grub_cryptodisk_memberlist,
  1069. #endif
  1070. .next = 0
  1071. };
  1072. static char
  1073. hex (grub_uint8_t val)
  1074. {
  1075. if (val < 10)
  1076. return '0' + val;
  1077. return 'a' + val - 10;
  1078. }
  1079. /* Open a file named NAME and initialize FILE. */
  1080. static char *
  1081. luks_script_get (grub_size_t *sz)
  1082. {
  1083. grub_cryptodisk_t i;
  1084. grub_size_t size = 0;
  1085. char *ptr, *ret;
  1086. *sz = 0;
  1087. for (i = cryptodisk_list; i != NULL; i = i->next)
  1088. if (grub_strcmp (i->modname, "luks") == 0)
  1089. {
  1090. size += sizeof ("luks_mount ");
  1091. size += grub_strlen (i->uuid);
  1092. size += grub_strlen (i->cipher->cipher->name);
  1093. size += 54;
  1094. if (i->essiv_hash)
  1095. size += grub_strlen (i->essiv_hash->name);
  1096. size += i->keysize * 2;
  1097. }
  1098. ret = grub_malloc (size + 1);
  1099. if (!ret)
  1100. return 0;
  1101. ptr = ret;
  1102. for (i = cryptodisk_list; i != NULL; i = i->next)
  1103. if (grub_strcmp (i->modname, "luks") == 0)
  1104. {
  1105. unsigned j;
  1106. const char *iptr;
  1107. ptr = grub_stpcpy (ptr, "luks_mount ");
  1108. ptr = grub_stpcpy (ptr, i->uuid);
  1109. *ptr++ = ' ';
  1110. grub_snprintf (ptr, 21, "%" PRIuGRUB_UINT64_T " ", i->offset_sectors);
  1111. while (*ptr)
  1112. ptr++;
  1113. for (iptr = i->cipher->cipher->name; *iptr; iptr++)
  1114. *ptr++ = grub_tolower (*iptr);
  1115. switch (i->mode)
  1116. {
  1117. case GRUB_CRYPTODISK_MODE_ECB:
  1118. ptr = grub_stpcpy (ptr, "-ecb");
  1119. break;
  1120. case GRUB_CRYPTODISK_MODE_CBC:
  1121. ptr = grub_stpcpy (ptr, "-cbc");
  1122. break;
  1123. case GRUB_CRYPTODISK_MODE_PCBC:
  1124. ptr = grub_stpcpy (ptr, "-pcbc");
  1125. break;
  1126. case GRUB_CRYPTODISK_MODE_XTS:
  1127. ptr = grub_stpcpy (ptr, "-xts");
  1128. break;
  1129. case GRUB_CRYPTODISK_MODE_LRW:
  1130. ptr = grub_stpcpy (ptr, "-lrw");
  1131. break;
  1132. }
  1133. switch (i->mode_iv)
  1134. {
  1135. case GRUB_CRYPTODISK_MODE_IV_NULL:
  1136. ptr = grub_stpcpy (ptr, "-null");
  1137. break;
  1138. case GRUB_CRYPTODISK_MODE_IV_PLAIN:
  1139. ptr = grub_stpcpy (ptr, "-plain");
  1140. break;
  1141. case GRUB_CRYPTODISK_MODE_IV_PLAIN64:
  1142. ptr = grub_stpcpy (ptr, "-plain64");
  1143. break;
  1144. case GRUB_CRYPTODISK_MODE_IV_BENBI:
  1145. ptr = grub_stpcpy (ptr, "-benbi");
  1146. break;
  1147. case GRUB_CRYPTODISK_MODE_IV_ESSIV:
  1148. ptr = grub_stpcpy (ptr, "-essiv:");
  1149. ptr = grub_stpcpy (ptr, i->essiv_hash->name);
  1150. break;
  1151. case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64:
  1152. case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH:
  1153. break;
  1154. }
  1155. *ptr++ = ' ';
  1156. for (j = 0; j < i->keysize; j++)
  1157. {
  1158. *ptr++ = hex (i->key[j] >> 4);
  1159. *ptr++ = hex (i->key[j] & 0xf);
  1160. }
  1161. *ptr++ = '\n';
  1162. }
  1163. *ptr = '\0';
  1164. *sz = ptr - ret;
  1165. return ret;
  1166. }
  1167. struct grub_procfs_entry luks_script =
  1168. {
  1169. .name = "luks_script",
  1170. .get_contents = luks_script_get
  1171. };
  1172. static grub_extcmd_t cmd;
  1173. GRUB_MOD_INIT (cryptodisk)
  1174. {
  1175. grub_disk_dev_register (&grub_cryptodisk_dev);
  1176. cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0,
  1177. N_("SOURCE|-u UUID|-a|-b"),
  1178. N_("Mount a crypto device."), options);
  1179. grub_procfs_register ("luks_script", &luks_script);
  1180. }
  1181. GRUB_MOD_FINI (cryptodisk)
  1182. {
  1183. grub_disk_dev_unregister (&grub_cryptodisk_dev);
  1184. cryptodisk_cleanup ();
  1185. grub_unregister_extcmd (cmd);
  1186. grub_procfs_unregister (&luks_script);
  1187. }