cryptodisk.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154
  1. /*
  2. * GRUB -- GRand Unified Bootloader
  3. * Copyright (C) 2003,2007,2010,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/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, int do_encrypt)
  206. {
  207. grub_size_t i;
  208. gcry_err_code_t err;
  209. if (dev->cipher->cipher->blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE)
  210. return GPG_ERR_INV_ARG;
  211. /* The only mode without IV. */
  212. if (dev->mode == GRUB_CRYPTODISK_MODE_ECB && !dev->rekey)
  213. return (do_encrypt ? grub_crypto_ecb_encrypt (dev->cipher, data, data, len)
  214. : grub_crypto_ecb_decrypt (dev->cipher, data, data, len));
  215. for (i = 0; i < len; i += (1U << dev->log_sector_size))
  216. {
  217. grub_size_t sz = ((dev->cipher->cipher->blocksize
  218. + sizeof (grub_uint32_t) - 1)
  219. / sizeof (grub_uint32_t));
  220. grub_uint32_t iv[(GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE + 3) / 4];
  221. if (dev->rekey)
  222. {
  223. grub_uint64_t zone = sector >> dev->rekey_shift;
  224. if (zone != dev->last_rekey)
  225. {
  226. err = dev->rekey (dev, zone);
  227. if (err)
  228. return err;
  229. dev->last_rekey = zone;
  230. }
  231. }
  232. grub_memset (iv, 0, sizeof (iv));
  233. switch (dev->mode_iv)
  234. {
  235. case GRUB_CRYPTODISK_MODE_IV_NULL:
  236. break;
  237. case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH:
  238. {
  239. grub_uint64_t tmp;
  240. void *ctx;
  241. ctx = grub_zalloc (dev->iv_hash->contextsize);
  242. if (!ctx)
  243. return GPG_ERR_OUT_OF_MEMORY;
  244. tmp = grub_cpu_to_le64 (sector << dev->log_sector_size);
  245. dev->iv_hash->init (ctx);
  246. dev->iv_hash->write (ctx, dev->iv_prefix, dev->iv_prefix_len);
  247. dev->iv_hash->write (ctx, &tmp, sizeof (tmp));
  248. dev->iv_hash->final (ctx);
  249. grub_memcpy (iv, dev->iv_hash->read (ctx), sizeof (iv));
  250. grub_free (ctx);
  251. }
  252. break;
  253. case GRUB_CRYPTODISK_MODE_IV_PLAIN64:
  254. iv[1] = grub_cpu_to_le32 (sector >> 32);
  255. case GRUB_CRYPTODISK_MODE_IV_PLAIN:
  256. iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF);
  257. break;
  258. case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64:
  259. iv[1] = grub_cpu_to_le32 (sector >> (32 - dev->log_sector_size));
  260. iv[0] = grub_cpu_to_le32 ((sector << dev->log_sector_size)
  261. & 0xFFFFFFFF);
  262. break;
  263. case GRUB_CRYPTODISK_MODE_IV_BENBI:
  264. {
  265. grub_uint64_t num = (sector << dev->benbi_log) + 1;
  266. iv[sz - 2] = grub_cpu_to_be32 (num >> 32);
  267. iv[sz - 1] = grub_cpu_to_be32 (num & 0xFFFFFFFF);
  268. }
  269. break;
  270. case GRUB_CRYPTODISK_MODE_IV_ESSIV:
  271. iv[0] = grub_cpu_to_le32 (sector & 0xFFFFFFFF);
  272. err = grub_crypto_ecb_encrypt (dev->essiv_cipher, iv, iv,
  273. dev->cipher->cipher->blocksize);
  274. if (err)
  275. return err;
  276. }
  277. switch (dev->mode)
  278. {
  279. case GRUB_CRYPTODISK_MODE_CBC:
  280. if (do_encrypt)
  281. err = grub_crypto_cbc_encrypt (dev->cipher, data + i, data + i,
  282. (1U << dev->log_sector_size), iv);
  283. else
  284. err = grub_crypto_cbc_decrypt (dev->cipher, data + i, data + i,
  285. (1U << dev->log_sector_size), iv);
  286. if (err)
  287. return err;
  288. break;
  289. case GRUB_CRYPTODISK_MODE_PCBC:
  290. if (do_encrypt)
  291. err = grub_crypto_pcbc_encrypt (dev->cipher, data + i, data + i,
  292. (1U << dev->log_sector_size), iv);
  293. else
  294. err = grub_crypto_pcbc_decrypt (dev->cipher, data + i, data + i,
  295. (1U << dev->log_sector_size), iv);
  296. if (err)
  297. return err;
  298. break;
  299. case GRUB_CRYPTODISK_MODE_XTS:
  300. {
  301. unsigned j;
  302. err = grub_crypto_ecb_encrypt (dev->secondary_cipher, iv, iv,
  303. dev->cipher->cipher->blocksize);
  304. if (err)
  305. return err;
  306. for (j = 0; j < (1U << dev->log_sector_size);
  307. j += dev->cipher->cipher->blocksize)
  308. {
  309. grub_crypto_xor (data + i + j, data + i + j, iv,
  310. dev->cipher->cipher->blocksize);
  311. if (do_encrypt)
  312. err = grub_crypto_ecb_encrypt (dev->cipher, data + i + j,
  313. data + i + j,
  314. dev->cipher->cipher->blocksize);
  315. else
  316. err = grub_crypto_ecb_decrypt (dev->cipher, data + i + j,
  317. data + i + j,
  318. dev->cipher->cipher->blocksize);
  319. if (err)
  320. return err;
  321. grub_crypto_xor (data + i + j, data + i + j, iv,
  322. dev->cipher->cipher->blocksize);
  323. gf_mul_x ((grub_uint8_t *) iv);
  324. }
  325. }
  326. break;
  327. case GRUB_CRYPTODISK_MODE_LRW:
  328. {
  329. struct lrw_sector sec;
  330. generate_lrw_sector (&sec, dev, (grub_uint8_t *) iv);
  331. lrw_xor (&sec, dev, data + i);
  332. if (do_encrypt)
  333. err = grub_crypto_ecb_encrypt (dev->cipher, data + i,
  334. data + i,
  335. (1U << dev->log_sector_size));
  336. else
  337. err = grub_crypto_ecb_decrypt (dev->cipher, data + i,
  338. data + i,
  339. (1U << dev->log_sector_size));
  340. if (err)
  341. return err;
  342. lrw_xor (&sec, dev, data + i);
  343. }
  344. break;
  345. case GRUB_CRYPTODISK_MODE_ECB:
  346. if (do_encrypt)
  347. err = grub_crypto_ecb_encrypt (dev->cipher, data + i, data + i,
  348. (1U << dev->log_sector_size));
  349. else
  350. err = grub_crypto_ecb_decrypt (dev->cipher, data + i, data + i,
  351. (1U << dev->log_sector_size));
  352. if (err)
  353. return err;
  354. break;
  355. default:
  356. return GPG_ERR_NOT_IMPLEMENTED;
  357. }
  358. sector++;
  359. }
  360. return GPG_ERR_NO_ERROR;
  361. }
  362. gcry_err_code_t
  363. grub_cryptodisk_decrypt (struct grub_cryptodisk *dev,
  364. grub_uint8_t * data, grub_size_t len,
  365. grub_disk_addr_t sector)
  366. {
  367. return grub_cryptodisk_endecrypt (dev, data, len, sector, 0);
  368. }
  369. gcry_err_code_t
  370. grub_cryptodisk_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, grub_size_t keysize)
  371. {
  372. gcry_err_code_t err;
  373. int real_keysize;
  374. real_keysize = keysize;
  375. if (dev->mode == GRUB_CRYPTODISK_MODE_XTS)
  376. real_keysize /= 2;
  377. if (dev->mode == GRUB_CRYPTODISK_MODE_LRW)
  378. real_keysize -= dev->cipher->cipher->blocksize;
  379. /* Set the PBKDF2 output as the cipher key. */
  380. err = grub_crypto_cipher_set_key (dev->cipher, key, real_keysize);
  381. if (err)
  382. return err;
  383. grub_memcpy (dev->key, key, keysize);
  384. dev->keysize = keysize;
  385. /* Configure ESSIV if necessary. */
  386. if (dev->mode_iv == GRUB_CRYPTODISK_MODE_IV_ESSIV)
  387. {
  388. grub_size_t essiv_keysize = dev->essiv_hash->mdlen;
  389. grub_uint8_t hashed_key[GRUB_CRYPTO_MAX_MDLEN];
  390. if (essiv_keysize > GRUB_CRYPTO_MAX_MDLEN)
  391. return GPG_ERR_INV_ARG;
  392. grub_crypto_hash (dev->essiv_hash, hashed_key, key, keysize);
  393. err = grub_crypto_cipher_set_key (dev->essiv_cipher,
  394. hashed_key, essiv_keysize);
  395. if (err)
  396. return err;
  397. }
  398. if (dev->mode == GRUB_CRYPTODISK_MODE_XTS)
  399. {
  400. err = grub_crypto_cipher_set_key (dev->secondary_cipher,
  401. key + real_keysize,
  402. keysize / 2);
  403. if (err)
  404. return err;
  405. }
  406. if (dev->mode == GRUB_CRYPTODISK_MODE_LRW)
  407. {
  408. unsigned i;
  409. grub_uint8_t idx[GRUB_CRYPTODISK_GF_BYTES];
  410. grub_free (dev->lrw_precalc);
  411. grub_memcpy (dev->lrw_key, key + real_keysize,
  412. dev->cipher->cipher->blocksize);
  413. dev->lrw_precalc = grub_malloc ((1U << dev->log_sector_size));
  414. if (!dev->lrw_precalc)
  415. return GPG_ERR_OUT_OF_MEMORY;
  416. grub_memset (idx, 0, GRUB_CRYPTODISK_GF_BYTES);
  417. for (i = 0; i < (1U << dev->log_sector_size);
  418. i += GRUB_CRYPTODISK_GF_BYTES)
  419. {
  420. idx[GRUB_CRYPTODISK_GF_BYTES - 1] = i / GRUB_CRYPTODISK_GF_BYTES;
  421. gf_mul_be (dev->lrw_precalc + i, idx, dev->lrw_key);
  422. }
  423. }
  424. return GPG_ERR_NO_ERROR;
  425. }
  426. static int
  427. grub_cryptodisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
  428. grub_disk_pull_t pull)
  429. {
  430. grub_cryptodisk_t i;
  431. if (pull != GRUB_DISK_PULL_NONE)
  432. return 0;
  433. for (i = cryptodisk_list; i != NULL; i = i->next)
  434. {
  435. char buf[30];
  436. grub_snprintf (buf, sizeof (buf), "crypto%lu", i->id);
  437. if (hook (buf, hook_data))
  438. return 1;
  439. }
  440. return GRUB_ERR_NONE;
  441. }
  442. static grub_err_t
  443. grub_cryptodisk_open (const char *name, grub_disk_t disk)
  444. {
  445. grub_cryptodisk_t dev;
  446. if (grub_memcmp (name, "crypto", sizeof ("crypto") - 1) != 0)
  447. return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device");
  448. if (grub_memcmp (name, "cryptouuid/", sizeof ("cryptouuid/") - 1) == 0)
  449. {
  450. for (dev = cryptodisk_list; dev != NULL; dev = dev->next)
  451. if (grub_strcasecmp (name + sizeof ("cryptouuid/") - 1, dev->uuid) == 0)
  452. break;
  453. }
  454. else
  455. {
  456. unsigned long id = grub_strtoul (name + sizeof ("crypto") - 1, 0, 0);
  457. if (grub_errno)
  458. return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device");
  459. /* Search for requested device in the list of CRYPTODISK devices. */
  460. for (dev = cryptodisk_list; dev != NULL; dev = dev->next)
  461. if (dev->id == id)
  462. break;
  463. }
  464. if (!dev)
  465. return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device");
  466. disk->log_sector_size = dev->log_sector_size;
  467. #ifdef GRUB_UTIL
  468. if (dev->cheat)
  469. {
  470. if (!GRUB_UTIL_FD_IS_VALID (dev->cheat_fd))
  471. dev->cheat_fd = grub_util_fd_open (dev->cheat, GRUB_UTIL_FD_O_RDONLY);
  472. if (!GRUB_UTIL_FD_IS_VALID (dev->cheat_fd))
  473. return grub_error (GRUB_ERR_IO, N_("cannot open `%s': %s"),
  474. dev->cheat, grub_util_fd_strerror ());
  475. }
  476. #endif
  477. if (!dev->source_disk)
  478. {
  479. grub_dprintf ("cryptodisk", "Opening device %s\n", name);
  480. /* Try to open the source disk and populate the requested disk. */
  481. dev->source_disk = grub_disk_open (dev->source);
  482. if (!dev->source_disk)
  483. return grub_errno;
  484. }
  485. disk->data = dev;
  486. disk->total_sectors = dev->total_length;
  487. disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE;
  488. disk->id = dev->id;
  489. dev->ref++;
  490. return GRUB_ERR_NONE;
  491. }
  492. static void
  493. grub_cryptodisk_close (grub_disk_t disk)
  494. {
  495. grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data;
  496. grub_dprintf ("cryptodisk", "Closing disk\n");
  497. dev->ref--;
  498. if (dev->ref != 0)
  499. return;
  500. #ifdef GRUB_UTIL
  501. if (dev->cheat)
  502. {
  503. grub_util_fd_close (dev->cheat_fd);
  504. dev->cheat_fd = GRUB_UTIL_FD_INVALID;
  505. }
  506. #endif
  507. grub_disk_close (dev->source_disk);
  508. dev->source_disk = NULL;
  509. }
  510. static grub_err_t
  511. grub_cryptodisk_read (grub_disk_t disk, grub_disk_addr_t sector,
  512. grub_size_t size, char *buf)
  513. {
  514. grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data;
  515. grub_err_t err;
  516. gcry_err_code_t gcry_err;
  517. #ifdef GRUB_UTIL
  518. if (dev->cheat)
  519. {
  520. int r;
  521. r = grub_util_fd_seek (dev->cheat_fd, sector << disk->log_sector_size);
  522. if (r)
  523. return grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot seek `%s': %s"),
  524. dev->cheat, grub_util_fd_strerror ());
  525. if (grub_util_fd_read (dev->cheat_fd, buf, size << disk->log_sector_size)
  526. != (ssize_t) (size << disk->log_sector_size))
  527. return grub_error (GRUB_ERR_READ_ERROR, N_("cannot read `%s': %s"),
  528. dev->cheat, grub_util_fd_strerror ());
  529. return GRUB_ERR_NONE;
  530. }
  531. #endif
  532. grub_dprintf ("cryptodisk",
  533. "Reading %" PRIuGRUB_SIZE " sectors from sector 0x%"
  534. PRIxGRUB_UINT64_T " with offset of %" PRIuGRUB_UINT64_T "\n",
  535. size, sector, dev->offset);
  536. err = grub_disk_read (dev->source_disk,
  537. (sector << (disk->log_sector_size
  538. - GRUB_DISK_SECTOR_BITS)) + dev->offset, 0,
  539. size << disk->log_sector_size, buf);
  540. if (err)
  541. {
  542. grub_dprintf ("cryptodisk", "grub_disk_read failed with error %d\n", err);
  543. return err;
  544. }
  545. gcry_err = grub_cryptodisk_endecrypt (dev, (grub_uint8_t *) buf,
  546. size << disk->log_sector_size,
  547. sector, 0);
  548. return grub_crypto_gcry_error (gcry_err);
  549. }
  550. static grub_err_t
  551. grub_cryptodisk_write (grub_disk_t disk, grub_disk_addr_t sector,
  552. grub_size_t size, const char *buf)
  553. {
  554. grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data;
  555. gcry_err_code_t gcry_err;
  556. char *tmp;
  557. grub_err_t err;
  558. #ifdef GRUB_UTIL
  559. if (dev->cheat)
  560. {
  561. int r;
  562. r = grub_util_fd_seek (dev->cheat_fd, sector << disk->log_sector_size);
  563. if (r)
  564. return grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot seek `%s': %s"),
  565. dev->cheat, grub_util_fd_strerror ());
  566. if (grub_util_fd_write (dev->cheat_fd, buf, size << disk->log_sector_size)
  567. != (ssize_t) (size << disk->log_sector_size))
  568. return grub_error (GRUB_ERR_READ_ERROR, N_("cannot read `%s': %s"),
  569. dev->cheat, grub_util_fd_strerror ());
  570. return GRUB_ERR_NONE;
  571. }
  572. #endif
  573. tmp = grub_malloc (size << disk->log_sector_size);
  574. if (!tmp)
  575. return grub_errno;
  576. grub_memcpy (tmp, buf, size << disk->log_sector_size);
  577. grub_dprintf ("cryptodisk",
  578. "Writing %" PRIuGRUB_SIZE " sectors to sector 0x%"
  579. PRIxGRUB_UINT64_T " with offset of %" PRIuGRUB_UINT64_T "\n",
  580. size, sector, dev->offset);
  581. gcry_err = grub_cryptodisk_endecrypt (dev, (grub_uint8_t *) tmp,
  582. size << disk->log_sector_size,
  583. sector, 1);
  584. if (gcry_err)
  585. {
  586. grub_free (tmp);
  587. return grub_crypto_gcry_error (gcry_err);
  588. }
  589. /* Since ->write was called so disk.mod is loaded but be paranoid */
  590. if (grub_disk_write_weak)
  591. err = grub_disk_write_weak (dev->source_disk,
  592. (sector << (disk->log_sector_size
  593. - GRUB_DISK_SECTOR_BITS))
  594. + dev->offset,
  595. 0, size << disk->log_sector_size, tmp);
  596. else
  597. err = grub_error (GRUB_ERR_BUG, "disk.mod not loaded");
  598. grub_free (tmp);
  599. return err;
  600. }
  601. #ifdef GRUB_UTIL
  602. static grub_disk_memberlist_t
  603. grub_cryptodisk_memberlist (grub_disk_t disk)
  604. {
  605. grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data;
  606. grub_disk_memberlist_t list = NULL;
  607. list = grub_malloc (sizeof (*list));
  608. if (list)
  609. {
  610. list->disk = dev->source_disk;
  611. list->next = NULL;
  612. }
  613. return list;
  614. }
  615. #endif
  616. static void
  617. cryptodisk_cleanup (void)
  618. {
  619. #if 0
  620. grub_cryptodisk_t dev = cryptodisk_list;
  621. grub_cryptodisk_t tmp;
  622. while (dev != NULL)
  623. {
  624. grub_free (dev->source);
  625. grub_free (dev->cipher);
  626. grub_free (dev->secondary_cipher);
  627. grub_free (dev->essiv_cipher);
  628. tmp = dev->next;
  629. grub_free (dev);
  630. dev = tmp;
  631. }
  632. #endif
  633. }
  634. grub_err_t
  635. grub_cryptodisk_insert (grub_cryptodisk_t newdev, const char *name,
  636. grub_disk_t source)
  637. {
  638. newdev->source = grub_strdup (name);
  639. if (!newdev->source)
  640. {
  641. grub_free (newdev);
  642. return grub_errno;
  643. }
  644. newdev->id = last_cryptodisk_id++;
  645. newdev->source_id = source->id;
  646. newdev->source_dev_id = source->dev->id;
  647. newdev->partition_start = grub_partition_get_start (source->partition);
  648. newdev->next = cryptodisk_list;
  649. cryptodisk_list = newdev;
  650. return GRUB_ERR_NONE;
  651. }
  652. grub_cryptodisk_t
  653. grub_cryptodisk_get_by_uuid (const char *uuid)
  654. {
  655. grub_cryptodisk_t dev;
  656. for (dev = cryptodisk_list; dev != NULL; dev = dev->next)
  657. if (grub_strcasecmp (dev->uuid, uuid) == 0)
  658. return dev;
  659. return NULL;
  660. }
  661. grub_cryptodisk_t
  662. grub_cryptodisk_get_by_source_disk (grub_disk_t disk)
  663. {
  664. grub_cryptodisk_t dev;
  665. for (dev = cryptodisk_list; dev != NULL; dev = dev->next)
  666. if (dev->source_id == disk->id && dev->source_dev_id == disk->dev->id)
  667. if ((disk->partition && grub_partition_get_start (disk->partition) == dev->partition_start) ||
  668. (!disk->partition && dev->partition_start == 0))
  669. return dev;
  670. return NULL;
  671. }
  672. #ifdef GRUB_UTIL
  673. grub_err_t
  674. grub_cryptodisk_cheat_insert (grub_cryptodisk_t newdev, const char *name,
  675. grub_disk_t source, const char *cheat)
  676. {
  677. newdev->cheat = grub_strdup (cheat);
  678. newdev->source = grub_strdup (name);
  679. if (!newdev->source || !newdev->cheat)
  680. {
  681. grub_free (newdev->source);
  682. grub_free (newdev->cheat);
  683. return grub_errno;
  684. }
  685. newdev->cheat_fd = GRUB_UTIL_FD_INVALID;
  686. newdev->source_id = source->id;
  687. newdev->source_dev_id = source->dev->id;
  688. newdev->partition_start = grub_partition_get_start (source->partition);
  689. newdev->id = last_cryptodisk_id++;
  690. newdev->next = cryptodisk_list;
  691. cryptodisk_list = newdev;
  692. return GRUB_ERR_NONE;
  693. }
  694. void
  695. grub_util_cryptodisk_get_abstraction (grub_disk_t disk,
  696. void (*cb) (const char *val, void *data),
  697. void *data)
  698. {
  699. grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data;
  700. cb ("cryptodisk", data);
  701. cb (dev->modname, data);
  702. if (dev->cipher)
  703. cb (dev->cipher->cipher->modname, data);
  704. if (dev->secondary_cipher)
  705. cb (dev->secondary_cipher->cipher->modname, data);
  706. if (dev->essiv_cipher)
  707. cb (dev->essiv_cipher->cipher->modname, data);
  708. if (dev->hash)
  709. cb (dev->hash->modname, data);
  710. if (dev->essiv_hash)
  711. cb (dev->essiv_hash->modname, data);
  712. if (dev->iv_hash)
  713. cb (dev->iv_hash->modname, data);
  714. }
  715. const char *
  716. grub_util_cryptodisk_get_uuid (grub_disk_t disk)
  717. {
  718. grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data;
  719. return dev->uuid;
  720. }
  721. #endif
  722. static int check_boot, have_it;
  723. static char *search_uuid;
  724. static void
  725. cryptodisk_close (grub_cryptodisk_t dev)
  726. {
  727. grub_crypto_cipher_close (dev->cipher);
  728. grub_crypto_cipher_close (dev->secondary_cipher);
  729. grub_crypto_cipher_close (dev->essiv_cipher);
  730. grub_free (dev);
  731. }
  732. static grub_err_t
  733. grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source)
  734. {
  735. grub_err_t err;
  736. grub_cryptodisk_t dev;
  737. grub_cryptodisk_dev_t cr;
  738. dev = grub_cryptodisk_get_by_source_disk (source);
  739. if (dev)
  740. return GRUB_ERR_NONE;
  741. FOR_CRYPTODISK_DEVS (cr)
  742. {
  743. dev = cr->scan (source, search_uuid, check_boot);
  744. if (grub_errno)
  745. return grub_errno;
  746. if (!dev)
  747. continue;
  748. err = cr->recover_key (source, dev);
  749. if (err)
  750. {
  751. cryptodisk_close (dev);
  752. return err;
  753. }
  754. grub_cryptodisk_insert (dev, name, source);
  755. have_it = 1;
  756. return GRUB_ERR_NONE;
  757. }
  758. return GRUB_ERR_NONE;
  759. }
  760. #ifdef GRUB_UTIL
  761. #include <grub/util/misc.h>
  762. grub_err_t
  763. grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat)
  764. {
  765. grub_err_t err;
  766. grub_cryptodisk_t dev;
  767. grub_cryptodisk_dev_t cr;
  768. grub_disk_t source;
  769. /* Try to open disk. */
  770. source = grub_disk_open (sourcedev);
  771. if (!source)
  772. return grub_errno;
  773. dev = grub_cryptodisk_get_by_source_disk (source);
  774. if (dev)
  775. {
  776. grub_disk_close (source);
  777. return GRUB_ERR_NONE;
  778. }
  779. FOR_CRYPTODISK_DEVS (cr)
  780. {
  781. dev = cr->scan (source, search_uuid, check_boot);
  782. if (grub_errno)
  783. return grub_errno;
  784. if (!dev)
  785. continue;
  786. grub_util_info ("cheatmounted %s (%s) at %s", sourcedev, dev->modname,
  787. cheat);
  788. err = grub_cryptodisk_cheat_insert (dev, sourcedev, source, cheat);
  789. grub_disk_close (source);
  790. if (err)
  791. grub_free (dev);
  792. return GRUB_ERR_NONE;
  793. }
  794. grub_disk_close (source);
  795. return GRUB_ERR_NONE;
  796. }
  797. #endif
  798. static int
  799. grub_cryptodisk_scan_device (const char *name,
  800. void *data __attribute__ ((unused)))
  801. {
  802. grub_err_t err;
  803. grub_disk_t source;
  804. /* Try to open disk. */
  805. source = grub_disk_open (name);
  806. if (!source)
  807. {
  808. grub_print_error ();
  809. return 0;
  810. }
  811. err = grub_cryptodisk_scan_device_real (name, source);
  812. grub_disk_close (source);
  813. if (err)
  814. grub_print_error ();
  815. return have_it && search_uuid ? 1 : 0;
  816. }
  817. static grub_err_t
  818. grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
  819. {
  820. struct grub_arg_list *state = ctxt->state;
  821. if (argc < 1 && !state[1].set && !state[2].set)
  822. return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
  823. have_it = 0;
  824. if (state[0].set)
  825. {
  826. grub_cryptodisk_t dev;
  827. dev = grub_cryptodisk_get_by_uuid (args[0]);
  828. if (dev)
  829. {
  830. grub_dprintf ("cryptodisk",
  831. "already mounted as crypto%lu\n", dev->id);
  832. return GRUB_ERR_NONE;
  833. }
  834. check_boot = state[2].set;
  835. search_uuid = args[0];
  836. grub_device_iterate (&grub_cryptodisk_scan_device, NULL);
  837. search_uuid = NULL;
  838. if (!have_it)
  839. return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found");
  840. return GRUB_ERR_NONE;
  841. }
  842. else if (state[1].set || (argc == 0 && state[2].set))
  843. {
  844. search_uuid = NULL;
  845. check_boot = state[2].set;
  846. grub_device_iterate (&grub_cryptodisk_scan_device, NULL);
  847. search_uuid = NULL;
  848. return GRUB_ERR_NONE;
  849. }
  850. else
  851. {
  852. grub_err_t err;
  853. grub_disk_t disk;
  854. grub_cryptodisk_t dev;
  855. char *diskname;
  856. char *disklast = NULL;
  857. grub_size_t len;
  858. search_uuid = NULL;
  859. check_boot = state[2].set;
  860. diskname = args[0];
  861. len = grub_strlen (diskname);
  862. if (len && diskname[0] == '(' && diskname[len - 1] == ')')
  863. {
  864. disklast = &diskname[len - 1];
  865. *disklast = '\0';
  866. diskname++;
  867. }
  868. disk = grub_disk_open (diskname);
  869. if (!disk)
  870. {
  871. if (disklast)
  872. *disklast = ')';
  873. return grub_errno;
  874. }
  875. dev = grub_cryptodisk_get_by_source_disk (disk);
  876. if (dev)
  877. {
  878. grub_dprintf ("cryptodisk", "already mounted as crypto%lu\n", dev->id);
  879. grub_disk_close (disk);
  880. if (disklast)
  881. *disklast = ')';
  882. return GRUB_ERR_NONE;
  883. }
  884. err = grub_cryptodisk_scan_device_real (diskname, disk);
  885. grub_disk_close (disk);
  886. if (disklast)
  887. *disklast = ')';
  888. return err;
  889. }
  890. }
  891. static struct grub_disk_dev grub_cryptodisk_dev = {
  892. .name = "cryptodisk",
  893. .id = GRUB_DISK_DEVICE_CRYPTODISK_ID,
  894. .iterate = grub_cryptodisk_iterate,
  895. .open = grub_cryptodisk_open,
  896. .close = grub_cryptodisk_close,
  897. .read = grub_cryptodisk_read,
  898. .write = grub_cryptodisk_write,
  899. #ifdef GRUB_UTIL
  900. .memberlist = grub_cryptodisk_memberlist,
  901. #endif
  902. .next = 0
  903. };
  904. static char
  905. hex (grub_uint8_t val)
  906. {
  907. if (val < 10)
  908. return '0' + val;
  909. return 'a' + val - 10;
  910. }
  911. /* Open a file named NAME and initialize FILE. */
  912. static char *
  913. luks_script_get (grub_size_t *sz)
  914. {
  915. grub_cryptodisk_t i;
  916. grub_size_t size = 0;
  917. char *ptr, *ret;
  918. *sz = 0;
  919. for (i = cryptodisk_list; i != NULL; i = i->next)
  920. if (grub_strcmp (i->modname, "luks") == 0)
  921. {
  922. size += sizeof ("luks_mount ");
  923. size += grub_strlen (i->uuid);
  924. size += grub_strlen (i->cipher->cipher->name);
  925. size += 54;
  926. if (i->essiv_hash)
  927. size += grub_strlen (i->essiv_hash->name);
  928. size += i->keysize * 2;
  929. }
  930. ret = grub_malloc (size + 1);
  931. if (!ret)
  932. return 0;
  933. ptr = ret;
  934. for (i = cryptodisk_list; i != NULL; i = i->next)
  935. if (grub_strcmp (i->modname, "luks") == 0)
  936. {
  937. unsigned j;
  938. const char *iptr;
  939. ptr = grub_stpcpy (ptr, "luks_mount ");
  940. ptr = grub_stpcpy (ptr, i->uuid);
  941. *ptr++ = ' ';
  942. grub_snprintf (ptr, 21, "%" PRIuGRUB_UINT64_T " ", i->offset);
  943. while (*ptr)
  944. ptr++;
  945. for (iptr = i->cipher->cipher->name; *iptr; iptr++)
  946. *ptr++ = grub_tolower (*iptr);
  947. switch (i->mode)
  948. {
  949. case GRUB_CRYPTODISK_MODE_ECB:
  950. ptr = grub_stpcpy (ptr, "-ecb");
  951. break;
  952. case GRUB_CRYPTODISK_MODE_CBC:
  953. ptr = grub_stpcpy (ptr, "-cbc");
  954. break;
  955. case GRUB_CRYPTODISK_MODE_PCBC:
  956. ptr = grub_stpcpy (ptr, "-pcbc");
  957. break;
  958. case GRUB_CRYPTODISK_MODE_XTS:
  959. ptr = grub_stpcpy (ptr, "-xts");
  960. break;
  961. case GRUB_CRYPTODISK_MODE_LRW:
  962. ptr = grub_stpcpy (ptr, "-lrw");
  963. break;
  964. }
  965. switch (i->mode_iv)
  966. {
  967. case GRUB_CRYPTODISK_MODE_IV_NULL:
  968. ptr = grub_stpcpy (ptr, "-null");
  969. break;
  970. case GRUB_CRYPTODISK_MODE_IV_PLAIN:
  971. ptr = grub_stpcpy (ptr, "-plain");
  972. break;
  973. case GRUB_CRYPTODISK_MODE_IV_PLAIN64:
  974. ptr = grub_stpcpy (ptr, "-plain64");
  975. break;
  976. case GRUB_CRYPTODISK_MODE_IV_BENBI:
  977. ptr = grub_stpcpy (ptr, "-benbi");
  978. break;
  979. case GRUB_CRYPTODISK_MODE_IV_ESSIV:
  980. ptr = grub_stpcpy (ptr, "-essiv:");
  981. ptr = grub_stpcpy (ptr, i->essiv_hash->name);
  982. break;
  983. case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64:
  984. case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH:
  985. break;
  986. }
  987. *ptr++ = ' ';
  988. for (j = 0; j < i->keysize; j++)
  989. {
  990. *ptr++ = hex (i->key[j] >> 4);
  991. *ptr++ = hex (i->key[j] & 0xf);
  992. }
  993. *ptr++ = '\n';
  994. }
  995. *ptr = '\0';
  996. *sz = ptr - ret;
  997. return ret;
  998. }
  999. struct grub_procfs_entry luks_script =
  1000. {
  1001. .name = "luks_script",
  1002. .get_contents = luks_script_get
  1003. };
  1004. static grub_extcmd_t cmd;
  1005. GRUB_MOD_INIT (cryptodisk)
  1006. {
  1007. grub_disk_dev_register (&grub_cryptodisk_dev);
  1008. cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0,
  1009. N_("SOURCE|-u UUID|-a|-b"),
  1010. N_("Mount a crypto device."), options);
  1011. grub_procfs_register ("luks_script", &luks_script);
  1012. }
  1013. GRUB_MOD_FINI (cryptodisk)
  1014. {
  1015. grub_disk_dev_unregister (&grub_cryptodisk_dev);
  1016. cryptodisk_cleanup ();
  1017. grub_procfs_unregister (&luks_script);
  1018. }