cryptodisk.c 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784
  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/env.h>
  20. #include <grub/mm.h>
  21. #include <grub/misc.h>
  22. #include <grub/dl.h>
  23. #include <grub/extcmd.h>
  24. #include <grub/i18n.h>
  25. #include <grub/fs.h>
  26. #include <grub/file.h>
  27. #include <grub/procfs.h>
  28. #include <grub/partition.h>
  29. #include <grub/key_protector.h>
  30. #ifdef GRUB_UTIL
  31. #include <grub/emu/hostdisk.h>
  32. #endif
  33. GRUB_MOD_LICENSE ("GPLv3+");
  34. grub_cryptodisk_dev_t grub_cryptodisk_list;
  35. enum
  36. {
  37. OPTION_UUID,
  38. OPTION_ALL,
  39. OPTION_BOOT,
  40. OPTION_PASSWORD,
  41. OPTION_KEYFILE,
  42. OPTION_KEYFILE_OFFSET,
  43. OPTION_KEYFILE_SIZE,
  44. OPTION_HEADER,
  45. OPTION_PROTECTOR
  46. };
  47. static const struct grub_arg_option options[] =
  48. {
  49. {"uuid", 'u', 0, N_("Mount by UUID."), 0, 0},
  50. /* TRANSLATORS: It's still restricted to cryptodisks only. */
  51. {"all", 'a', 0, N_("Mount all."), 0, 0},
  52. {"boot", 'b', 0, N_("Mount all volumes with `boot' flag set."), 0, 0},
  53. {"password", 'p', 0, N_("Password to open volumes."), 0, ARG_TYPE_STRING},
  54. {"key-file", 'k', 0, N_("Key file"), 0, ARG_TYPE_STRING},
  55. {"keyfile-offset", 'O', 0, N_("Key file offset (bytes)"), 0, ARG_TYPE_INT},
  56. {"keyfile-size", 'S', 0, N_("Key file data size (bytes)"), 0, ARG_TYPE_INT},
  57. {"header", 'H', 0, N_("Read header from file"), 0, ARG_TYPE_STRING},
  58. {"protector", 'P', GRUB_ARG_OPTION_REPEATABLE,
  59. N_("Unlock volume(s) using key protector(s)."), 0, ARG_TYPE_STRING},
  60. {0, 0, 0, 0, 0, 0}
  61. };
  62. struct cryptodisk_read_hook_ctx
  63. {
  64. grub_file_t hdr_file;
  65. grub_disk_addr_t part_start;
  66. };
  67. typedef struct cryptodisk_read_hook_ctx *cryptodisk_read_hook_ctx_t;
  68. /* Our irreducible polynom is x^128+x^7+x^2+x+1. Lowest byte of it is: */
  69. #define GF_POLYNOM 0x87
  70. static inline int GF_PER_SECTOR (const struct grub_cryptodisk *dev)
  71. {
  72. return 1U << (dev->log_sector_size - GRUB_CRYPTODISK_GF_LOG_BYTES);
  73. }
  74. static grub_cryptodisk_t cryptodisk_list = NULL;
  75. static grub_uint8_t last_cryptodisk_id = 0;
  76. static void
  77. gf_mul_x (grub_uint8_t *g)
  78. {
  79. int over = 0, over2 = 0;
  80. unsigned j;
  81. for (j = 0; j < GRUB_CRYPTODISK_GF_BYTES; j++)
  82. {
  83. over2 = !!(g[j] & 0x80);
  84. g[j] <<= 1;
  85. g[j] |= over;
  86. over = over2;
  87. }
  88. if (over)
  89. g[0] ^= GF_POLYNOM;
  90. }
  91. static void
  92. gf_mul_x_be (grub_uint8_t *g)
  93. {
  94. int over = 0, over2 = 0;
  95. int j;
  96. for (j = (int) GRUB_CRYPTODISK_GF_BYTES - 1; j >= 0; j--)
  97. {
  98. over2 = !!(g[j] & 0x80);
  99. g[j] <<= 1;
  100. g[j] |= over;
  101. over = over2;
  102. }
  103. if (over)
  104. g[GRUB_CRYPTODISK_GF_BYTES - 1] ^= GF_POLYNOM;
  105. }
  106. static void
  107. gf_mul_be (grub_uint8_t *o, const grub_uint8_t *a, const grub_uint8_t *b)
  108. {
  109. unsigned i;
  110. grub_uint8_t t[GRUB_CRYPTODISK_GF_BYTES];
  111. grub_memset (o, 0, GRUB_CRYPTODISK_GF_BYTES);
  112. grub_memcpy (t, b, GRUB_CRYPTODISK_GF_BYTES);
  113. for (i = 0; i < GRUB_CRYPTODISK_GF_SIZE; i++)
  114. {
  115. if (((a[GRUB_CRYPTODISK_GF_BYTES - i / GRUB_CHAR_BIT - 1] >> (i % GRUB_CHAR_BIT))) & 1)
  116. grub_crypto_xor (o, o, t, GRUB_CRYPTODISK_GF_BYTES);
  117. gf_mul_x_be (t);
  118. }
  119. }
  120. static gcry_err_code_t
  121. grub_crypto_pcbc_decrypt (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->decrypt)
  129. return GPG_ERR_NOT_SUPPORTED;
  130. blocksize = cipher->cipher->blocksize;
  131. if (blocksize == 0 || (((blocksize - 1) & blocksize) != 0)
  132. || ((size & (blocksize - 1)) != 0))
  133. return GPG_ERR_INV_ARG;
  134. if (blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE)
  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. cipher->cipher->decrypt (cipher->ctx, outptr, inptr);
  142. grub_crypto_xor (outptr, outptr, iv, blocksize);
  143. grub_crypto_xor (iv, ivt, outptr, blocksize);
  144. }
  145. return GPG_ERR_NO_ERROR;
  146. }
  147. static gcry_err_code_t
  148. grub_crypto_pcbc_encrypt (grub_crypto_cipher_handle_t cipher,
  149. void *out, void *in, grub_size_t size,
  150. void *iv)
  151. {
  152. grub_uint8_t *inptr, *outptr, *end;
  153. grub_uint8_t ivt[GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE];
  154. grub_size_t blocksize;
  155. if (!cipher->cipher->encrypt)
  156. return GPG_ERR_NOT_SUPPORTED;
  157. blocksize = cipher->cipher->blocksize;
  158. if (blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE)
  159. return GPG_ERR_INV_ARG;
  160. if (blocksize == 0 || (((blocksize - 1) & blocksize) != 0)
  161. || ((size & (blocksize - 1)) != 0))
  162. return GPG_ERR_INV_ARG;
  163. end = (grub_uint8_t *) in + size;
  164. for (inptr = in, outptr = out; inptr < end;
  165. inptr += blocksize, outptr += blocksize)
  166. {
  167. grub_memcpy (ivt, inptr, blocksize);
  168. grub_crypto_xor (outptr, outptr, iv, blocksize);
  169. cipher->cipher->encrypt (cipher->ctx, outptr, inptr);
  170. grub_crypto_xor (iv, ivt, outptr, blocksize);
  171. }
  172. return GPG_ERR_NO_ERROR;
  173. }
  174. struct lrw_sector
  175. {
  176. grub_uint8_t low[GRUB_CRYPTODISK_GF_BYTES];
  177. grub_uint8_t high[GRUB_CRYPTODISK_GF_BYTES];
  178. grub_uint8_t low_byte, low_byte_c;
  179. };
  180. static void
  181. generate_lrw_sector (struct lrw_sector *sec,
  182. const struct grub_cryptodisk *dev,
  183. const grub_uint8_t *iv)
  184. {
  185. grub_uint8_t idx[GRUB_CRYPTODISK_GF_BYTES];
  186. grub_uint16_t c;
  187. int j;
  188. grub_memcpy (idx, iv, GRUB_CRYPTODISK_GF_BYTES);
  189. sec->low_byte = (idx[GRUB_CRYPTODISK_GF_BYTES - 1]
  190. & (GF_PER_SECTOR (dev) - 1));
  191. sec->low_byte_c = (((GF_PER_SECTOR (dev) - 1) & ~sec->low_byte) + 1);
  192. idx[GRUB_CRYPTODISK_GF_BYTES - 1] &= ~(GF_PER_SECTOR (dev) - 1);
  193. gf_mul_be (sec->low, dev->lrw_key, idx);
  194. if (!sec->low_byte)
  195. return;
  196. c = idx[GRUB_CRYPTODISK_GF_BYTES - 1] + GF_PER_SECTOR (dev);
  197. if (c & 0x100)
  198. {
  199. for (j = GRUB_CRYPTODISK_GF_BYTES - 2; j >= 0; j--)
  200. {
  201. idx[j]++;
  202. if (idx[j] != 0)
  203. break;
  204. }
  205. }
  206. idx[GRUB_CRYPTODISK_GF_BYTES - 1] = c;
  207. gf_mul_be (sec->high, dev->lrw_key, idx);
  208. }
  209. static void __attribute__ ((unused))
  210. lrw_xor (const struct lrw_sector *sec,
  211. const struct grub_cryptodisk *dev,
  212. grub_uint8_t *b)
  213. {
  214. unsigned i;
  215. for (i = 0; i < sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES;
  216. i += GRUB_CRYPTODISK_GF_BYTES)
  217. grub_crypto_xor (b + i, b + i, sec->low, GRUB_CRYPTODISK_GF_BYTES);
  218. grub_crypto_xor (b, b, dev->lrw_precalc + GRUB_CRYPTODISK_GF_BYTES * sec->low_byte,
  219. sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES);
  220. if (!sec->low_byte)
  221. return;
  222. for (i = sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES;
  223. i < (1U << dev->log_sector_size); i += GRUB_CRYPTODISK_GF_BYTES)
  224. grub_crypto_xor (b + i, b + i, sec->high, GRUB_CRYPTODISK_GF_BYTES);
  225. grub_crypto_xor (b + sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES,
  226. b + sec->low_byte_c * GRUB_CRYPTODISK_GF_BYTES,
  227. dev->lrw_precalc, sec->low_byte * GRUB_CRYPTODISK_GF_BYTES);
  228. }
  229. static gcry_err_code_t
  230. grub_cryptodisk_endecrypt (struct grub_cryptodisk *dev,
  231. grub_uint8_t * data, grub_size_t len,
  232. grub_disk_addr_t sector, grub_size_t log_sector_size,
  233. int do_encrypt)
  234. {
  235. grub_size_t i;
  236. gcry_err_code_t err;
  237. if (dev->cipher->cipher->blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE)
  238. return GPG_ERR_INV_ARG;
  239. /* The only mode without IV. */
  240. if (dev->mode == GRUB_CRYPTODISK_MODE_ECB && !dev->rekey)
  241. return (do_encrypt ? grub_crypto_ecb_encrypt (dev->cipher, data, data, len)
  242. : grub_crypto_ecb_decrypt (dev->cipher, data, data, len));
  243. for (i = 0; i < len; i += ((grub_size_t) 1 << log_sector_size))
  244. {
  245. grub_size_t sz = ((dev->cipher->cipher->blocksize
  246. + sizeof (grub_uint32_t) - 1)
  247. / sizeof (grub_uint32_t));
  248. grub_uint32_t iv[(GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE + 3) / 4];
  249. if (dev->rekey)
  250. {
  251. grub_uint64_t zone = sector >> dev->rekey_shift;
  252. if (zone != dev->last_rekey)
  253. {
  254. err = dev->rekey (dev, zone);
  255. if (err)
  256. return err;
  257. dev->last_rekey = zone;
  258. }
  259. }
  260. grub_memset (iv, 0, sizeof (iv));
  261. switch (dev->mode_iv)
  262. {
  263. case GRUB_CRYPTODISK_MODE_IV_NULL:
  264. break;
  265. case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH:
  266. {
  267. grub_uint64_t tmp;
  268. void *ctx;
  269. ctx = grub_zalloc (dev->iv_hash->contextsize);
  270. if (!ctx)
  271. return GPG_ERR_OUT_OF_MEMORY;
  272. tmp = grub_cpu_to_le64 (sector << log_sector_size);
  273. dev->iv_hash->init (ctx);
  274. dev->iv_hash->write (ctx, dev->iv_prefix, dev->iv_prefix_len);
  275. dev->iv_hash->write (ctx, &tmp, sizeof (tmp));
  276. dev->iv_hash->final (ctx);
  277. grub_memcpy (iv, dev->iv_hash->read (ctx), sizeof (iv));
  278. grub_free (ctx);
  279. }
  280. break;
  281. case GRUB_CRYPTODISK_MODE_IV_PLAIN64:
  282. case GRUB_CRYPTODISK_MODE_IV_PLAIN:
  283. /*
  284. * The IV is a 32 or 64 bit value of the dm-crypt native sector
  285. * number. If using 32 bit IV mode, zero out the most significant
  286. * 32 bits.
  287. */
  288. {
  289. grub_uint64_t iv64;
  290. iv64 = grub_cpu_to_le64 (sector << (log_sector_size
  291. - GRUB_CRYPTODISK_IV_LOG_SIZE));
  292. grub_set_unaligned64 (iv, iv64);
  293. if (dev->mode_iv == GRUB_CRYPTODISK_MODE_IV_PLAIN)
  294. iv[1] = 0;
  295. }
  296. break;
  297. case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64:
  298. /* The IV is the 64 bit byte offset of the sector. */
  299. iv[1] = grub_cpu_to_le32 (sector >> (GRUB_TYPE_BITS (iv[1])
  300. - log_sector_size));
  301. iv[0] = grub_cpu_to_le32 ((sector << log_sector_size)
  302. & GRUB_TYPE_U_MAX (iv[0]));
  303. break;
  304. case GRUB_CRYPTODISK_MODE_IV_BENBI:
  305. {
  306. grub_uint64_t num = (sector << dev->benbi_log) + 1;
  307. iv[sz - 2] = grub_cpu_to_be32 (num >> GRUB_TYPE_BITS (iv[0]));
  308. iv[sz - 1] = grub_cpu_to_be32 (num & GRUB_TYPE_U_MAX (iv[0]));
  309. }
  310. break;
  311. case GRUB_CRYPTODISK_MODE_IV_ESSIV:
  312. iv[0] = grub_cpu_to_le32 (sector & GRUB_TYPE_U_MAX (iv[0]));
  313. err = grub_crypto_ecb_encrypt (dev->essiv_cipher, iv, iv,
  314. dev->cipher->cipher->blocksize);
  315. if (err)
  316. return err;
  317. }
  318. switch (dev->mode)
  319. {
  320. case GRUB_CRYPTODISK_MODE_CBC:
  321. if (do_encrypt)
  322. err = grub_crypto_cbc_encrypt (dev->cipher, data + i, data + i,
  323. ((grub_size_t) 1 << log_sector_size), iv);
  324. else
  325. err = grub_crypto_cbc_decrypt (dev->cipher, data + i, data + i,
  326. ((grub_size_t) 1 << log_sector_size), iv);
  327. if (err)
  328. return err;
  329. break;
  330. case GRUB_CRYPTODISK_MODE_PCBC:
  331. if (do_encrypt)
  332. err = grub_crypto_pcbc_encrypt (dev->cipher, data + i, data + i,
  333. ((grub_size_t) 1 << log_sector_size), iv);
  334. else
  335. err = grub_crypto_pcbc_decrypt (dev->cipher, data + i, data + i,
  336. ((grub_size_t) 1 << log_sector_size), iv);
  337. if (err)
  338. return err;
  339. break;
  340. case GRUB_CRYPTODISK_MODE_XTS:
  341. {
  342. unsigned j;
  343. err = grub_crypto_ecb_encrypt (dev->secondary_cipher, iv, iv,
  344. dev->cipher->cipher->blocksize);
  345. if (err)
  346. return err;
  347. for (j = 0; j < (1U << log_sector_size);
  348. j += dev->cipher->cipher->blocksize)
  349. {
  350. grub_crypto_xor (data + i + j, data + i + j, iv,
  351. dev->cipher->cipher->blocksize);
  352. if (do_encrypt)
  353. err = grub_crypto_ecb_encrypt (dev->cipher, data + i + j,
  354. data + i + j,
  355. dev->cipher->cipher->blocksize);
  356. else
  357. err = grub_crypto_ecb_decrypt (dev->cipher, data + i + j,
  358. data + i + j,
  359. dev->cipher->cipher->blocksize);
  360. if (err)
  361. return err;
  362. grub_crypto_xor (data + i + j, data + i + j, iv,
  363. dev->cipher->cipher->blocksize);
  364. gf_mul_x ((grub_uint8_t *) iv);
  365. }
  366. }
  367. break;
  368. case GRUB_CRYPTODISK_MODE_LRW:
  369. {
  370. struct lrw_sector sec;
  371. generate_lrw_sector (&sec, dev, (grub_uint8_t *) iv);
  372. lrw_xor (&sec, dev, data + i);
  373. if (do_encrypt)
  374. err = grub_crypto_ecb_encrypt (dev->cipher, data + i,
  375. data + i,
  376. (1U << log_sector_size));
  377. else
  378. err = grub_crypto_ecb_decrypt (dev->cipher, data + i,
  379. data + i,
  380. (1U << log_sector_size));
  381. if (err)
  382. return err;
  383. lrw_xor (&sec, dev, data + i);
  384. }
  385. break;
  386. case GRUB_CRYPTODISK_MODE_ECB:
  387. if (do_encrypt)
  388. err = grub_crypto_ecb_encrypt (dev->cipher, data + i, data + i,
  389. (1U << log_sector_size));
  390. else
  391. err = grub_crypto_ecb_decrypt (dev->cipher, data + i, data + i,
  392. (1U << log_sector_size));
  393. if (err)
  394. return err;
  395. break;
  396. default:
  397. return GPG_ERR_NOT_IMPLEMENTED;
  398. }
  399. sector++;
  400. }
  401. return GPG_ERR_NO_ERROR;
  402. }
  403. gcry_err_code_t
  404. grub_cryptodisk_decrypt (struct grub_cryptodisk *dev,
  405. grub_uint8_t * data, grub_size_t len,
  406. grub_disk_addr_t sector, grub_size_t log_sector_size)
  407. {
  408. return grub_cryptodisk_endecrypt (dev, data, len, sector, log_sector_size, 0);
  409. }
  410. grub_err_t
  411. grub_cryptodisk_setcipher (grub_cryptodisk_t crypt, const char *ciphername, const char *ciphermode)
  412. {
  413. const char *cipheriv = NULL;
  414. grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL;
  415. grub_crypto_cipher_handle_t essiv_cipher = NULL;
  416. const gcry_md_spec_t *essiv_hash = NULL;
  417. const struct gcry_cipher_spec *ciph;
  418. grub_cryptodisk_mode_t mode;
  419. grub_cryptodisk_mode_iv_t mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64;
  420. int benbi_log = 0;
  421. grub_err_t ret = GRUB_ERR_NONE;
  422. ciph = grub_crypto_lookup_cipher_by_name (ciphername);
  423. if (!ciph)
  424. {
  425. ret = grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s isn't available",
  426. ciphername);
  427. goto err;
  428. }
  429. /* Configure the cipher used for the bulk data. */
  430. cipher = grub_crypto_cipher_open (ciph);
  431. if (!cipher)
  432. {
  433. ret = grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s could not be initialized",
  434. ciphername);
  435. goto err;
  436. }
  437. /* Configure the cipher mode. */
  438. if (grub_strcmp (ciphermode, "ecb") == 0)
  439. {
  440. mode = GRUB_CRYPTODISK_MODE_ECB;
  441. mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
  442. cipheriv = NULL;
  443. }
  444. else if (grub_strcmp (ciphermode, "plain") == 0)
  445. {
  446. mode = GRUB_CRYPTODISK_MODE_CBC;
  447. mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
  448. cipheriv = NULL;
  449. }
  450. else if (grub_memcmp (ciphermode, "cbc-", sizeof ("cbc-") - 1) == 0)
  451. {
  452. mode = GRUB_CRYPTODISK_MODE_CBC;
  453. cipheriv = ciphermode + sizeof ("cbc-") - 1;
  454. }
  455. else if (grub_memcmp (ciphermode, "pcbc-", sizeof ("pcbc-") - 1) == 0)
  456. {
  457. mode = GRUB_CRYPTODISK_MODE_PCBC;
  458. cipheriv = ciphermode + sizeof ("pcbc-") - 1;
  459. }
  460. else if (grub_memcmp (ciphermode, "xts-", sizeof ("xts-") - 1) == 0)
  461. {
  462. mode = GRUB_CRYPTODISK_MODE_XTS;
  463. cipheriv = ciphermode + sizeof ("xts-") - 1;
  464. secondary_cipher = grub_crypto_cipher_open (ciph);
  465. if (!secondary_cipher)
  466. {
  467. ret = grub_error (GRUB_ERR_FILE_NOT_FOUND,
  468. "Secondary cipher %s isn't available", ciphername);
  469. goto err;
  470. }
  471. if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
  472. {
  473. ret = grub_error (GRUB_ERR_BAD_ARGUMENT,
  474. "Unsupported XTS block size: %" PRIuGRUB_SIZE,
  475. cipher->cipher->blocksize);
  476. goto err;
  477. }
  478. if (secondary_cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
  479. {
  480. ret = grub_error (GRUB_ERR_BAD_ARGUMENT,
  481. "Unsupported XTS block size: %" PRIuGRUB_SIZE,
  482. secondary_cipher->cipher->blocksize);
  483. goto err;
  484. }
  485. }
  486. else if (grub_memcmp (ciphermode, "lrw-", sizeof ("lrw-") - 1) == 0)
  487. {
  488. mode = GRUB_CRYPTODISK_MODE_LRW;
  489. cipheriv = ciphermode + sizeof ("lrw-") - 1;
  490. if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
  491. {
  492. ret = grub_error (GRUB_ERR_BAD_ARGUMENT,
  493. "Unsupported LRW block size: %" PRIuGRUB_SIZE,
  494. cipher->cipher->blocksize);
  495. goto err;
  496. }
  497. }
  498. else
  499. {
  500. ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown cipher mode: %s",
  501. ciphermode);
  502. goto err;
  503. }
  504. if (cipheriv == NULL)
  505. ;
  506. else if (grub_memcmp (cipheriv, "plain64", sizeof ("plain64") - 1) == 0)
  507. mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64;
  508. else if (grub_memcmp (cipheriv, "plain", sizeof ("plain") - 1) == 0)
  509. mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
  510. else if (grub_memcmp (cipheriv, "benbi", sizeof ("benbi") - 1) == 0)
  511. {
  512. if (cipher->cipher->blocksize & (cipher->cipher->blocksize - 1)
  513. || cipher->cipher->blocksize == 0)
  514. grub_error (GRUB_ERR_BAD_ARGUMENT,
  515. "Unsupported benbi blocksize: %" PRIuGRUB_SIZE,
  516. cipher->cipher->blocksize);
  517. /* FIXME should we return an error here? */
  518. for (benbi_log = 0;
  519. (cipher->cipher->blocksize << benbi_log) < GRUB_DISK_SECTOR_SIZE;
  520. benbi_log++);
  521. mode_iv = GRUB_CRYPTODISK_MODE_IV_BENBI;
  522. }
  523. else if (grub_memcmp (cipheriv, "null", sizeof ("null") - 1) == 0)
  524. mode_iv = GRUB_CRYPTODISK_MODE_IV_NULL;
  525. else if (grub_memcmp (cipheriv, "essiv:", sizeof ("essiv:") - 1) == 0)
  526. {
  527. const char *hash_str = cipheriv + 6;
  528. mode_iv = GRUB_CRYPTODISK_MODE_IV_ESSIV;
  529. /* Configure the hash and cipher used for ESSIV. */
  530. essiv_hash = grub_crypto_lookup_md_by_name (hash_str);
  531. if (!essiv_hash)
  532. {
  533. ret = grub_error (GRUB_ERR_FILE_NOT_FOUND,
  534. "Couldn't load %s hash", hash_str);
  535. goto err;
  536. }
  537. essiv_cipher = grub_crypto_cipher_open (ciph);
  538. if (!essiv_cipher)
  539. {
  540. ret = grub_error (GRUB_ERR_FILE_NOT_FOUND,
  541. "Couldn't load %s cipher", ciphername);
  542. goto err;
  543. }
  544. }
  545. else
  546. {
  547. ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown IV mode: %s",
  548. cipheriv);
  549. goto err;
  550. }
  551. crypt->cipher = cipher;
  552. crypt->benbi_log = benbi_log;
  553. crypt->mode = mode;
  554. crypt->mode_iv = mode_iv;
  555. crypt->secondary_cipher = secondary_cipher;
  556. crypt->essiv_cipher = essiv_cipher;
  557. crypt->essiv_hash = essiv_hash;
  558. err:
  559. if (ret)
  560. {
  561. grub_crypto_cipher_close (cipher);
  562. grub_crypto_cipher_close (secondary_cipher);
  563. }
  564. return ret;
  565. }
  566. gcry_err_code_t
  567. grub_cryptodisk_setkey (grub_cryptodisk_t dev, grub_uint8_t *key, grub_size_t keysize)
  568. {
  569. gcry_err_code_t err;
  570. int real_keysize;
  571. real_keysize = keysize;
  572. if (dev->mode == GRUB_CRYPTODISK_MODE_XTS)
  573. real_keysize /= 2;
  574. if (dev->mode == GRUB_CRYPTODISK_MODE_LRW)
  575. real_keysize -= dev->cipher->cipher->blocksize;
  576. /* Set the PBKDF2 output as the cipher key. */
  577. err = grub_crypto_cipher_set_key (dev->cipher, key, real_keysize);
  578. if (err)
  579. return err;
  580. grub_memcpy (dev->key, key, keysize);
  581. dev->keysize = keysize;
  582. /* Configure ESSIV if necessary. */
  583. if (dev->mode_iv == GRUB_CRYPTODISK_MODE_IV_ESSIV)
  584. {
  585. grub_size_t essiv_keysize = dev->essiv_hash->mdlen;
  586. grub_uint8_t hashed_key[GRUB_CRYPTO_MAX_MDLEN];
  587. if (essiv_keysize > GRUB_CRYPTO_MAX_MDLEN)
  588. return GPG_ERR_INV_ARG;
  589. grub_crypto_hash (dev->essiv_hash, hashed_key, key, keysize);
  590. err = grub_crypto_cipher_set_key (dev->essiv_cipher,
  591. hashed_key, essiv_keysize);
  592. if (err)
  593. return err;
  594. }
  595. if (dev->mode == GRUB_CRYPTODISK_MODE_XTS)
  596. {
  597. err = grub_crypto_cipher_set_key (dev->secondary_cipher,
  598. key + real_keysize,
  599. keysize / 2);
  600. if (err)
  601. return err;
  602. }
  603. if (dev->mode == GRUB_CRYPTODISK_MODE_LRW)
  604. {
  605. unsigned i;
  606. grub_uint8_t idx[GRUB_CRYPTODISK_GF_BYTES];
  607. grub_free (dev->lrw_precalc);
  608. grub_memcpy (dev->lrw_key, key + real_keysize,
  609. dev->cipher->cipher->blocksize);
  610. dev->lrw_precalc = grub_malloc ((1U << dev->log_sector_size));
  611. if (!dev->lrw_precalc)
  612. return GPG_ERR_OUT_OF_MEMORY;
  613. grub_memset (idx, 0, GRUB_CRYPTODISK_GF_BYTES);
  614. for (i = 0; i < (1U << dev->log_sector_size);
  615. i += GRUB_CRYPTODISK_GF_BYTES)
  616. {
  617. idx[GRUB_CRYPTODISK_GF_BYTES - 1] = i / GRUB_CRYPTODISK_GF_BYTES;
  618. gf_mul_be (dev->lrw_precalc + i, idx, dev->lrw_key);
  619. }
  620. }
  621. return GPG_ERR_NO_ERROR;
  622. }
  623. static int
  624. grub_cryptodisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
  625. grub_disk_pull_t pull)
  626. {
  627. grub_cryptodisk_t i;
  628. if (pull != GRUB_DISK_PULL_NONE)
  629. return 0;
  630. for (i = cryptodisk_list; i != NULL; i = i->next)
  631. {
  632. char buf[30];
  633. grub_snprintf (buf, sizeof (buf), "crypto%lu", i->id);
  634. if (hook (buf, hook_data))
  635. return 1;
  636. }
  637. return GRUB_ERR_NONE;
  638. }
  639. static grub_err_t
  640. grub_cryptodisk_open (const char *name, grub_disk_t disk)
  641. {
  642. grub_cryptodisk_t dev;
  643. if (grub_memcmp (name, "crypto", sizeof ("crypto") - 1) != 0)
  644. return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device");
  645. if (grub_memcmp (name, "cryptouuid/", sizeof ("cryptouuid/") - 1) == 0)
  646. {
  647. for (dev = cryptodisk_list; dev != NULL; dev = dev->next)
  648. if (grub_uuidcasecmp (name + sizeof ("cryptouuid/") - 1, dev->uuid, sizeof (dev->uuid)) == 0)
  649. break;
  650. }
  651. else
  652. {
  653. unsigned long id = grub_strtoul (name + sizeof ("crypto") - 1, 0, 0);
  654. if (grub_errno)
  655. return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device");
  656. /* Search for requested device in the list of CRYPTODISK devices. */
  657. for (dev = cryptodisk_list; dev != NULL; dev = dev->next)
  658. if (dev->id == id)
  659. break;
  660. }
  661. if (!dev)
  662. return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device");
  663. #ifdef GRUB_UTIL
  664. if (dev->cheat)
  665. {
  666. grub_uint64_t cheat_dev_size;
  667. unsigned int cheat_log_sector_size;
  668. if (!GRUB_UTIL_FD_IS_VALID (dev->cheat_fd))
  669. dev->cheat_fd = grub_util_fd_open (dev->cheat, GRUB_UTIL_FD_O_RDONLY);
  670. if (!GRUB_UTIL_FD_IS_VALID (dev->cheat_fd))
  671. return grub_error (GRUB_ERR_IO, N_("cannot open `%s': %s"),
  672. dev->cheat, grub_util_fd_strerror ());
  673. /* Use the sector size and count of the cheat device. */
  674. cheat_dev_size = grub_util_get_fd_size (dev->cheat_fd, dev->cheat, &cheat_log_sector_size);
  675. if (cheat_dev_size == -1)
  676. {
  677. const char *errmsg = grub_util_fd_strerror ();
  678. grub_util_fd_close (dev->cheat_fd);
  679. dev->cheat_fd = GRUB_UTIL_FD_INVALID;
  680. return grub_error (GRUB_ERR_IO, N_("failed to query size of device `%s': %s"),
  681. dev->cheat, errmsg);
  682. }
  683. dev->log_sector_size = cheat_log_sector_size;
  684. dev->total_sectors = cheat_dev_size >> cheat_log_sector_size;
  685. }
  686. #endif
  687. if (!dev->source_disk)
  688. {
  689. grub_dprintf ("cryptodisk", "Opening device %s\n", name);
  690. /* Try to open the source disk and populate the requested disk. */
  691. dev->source_disk = grub_disk_open (dev->source);
  692. if (!dev->source_disk)
  693. return grub_errno;
  694. }
  695. disk->data = dev;
  696. disk->log_sector_size = dev->log_sector_size;
  697. disk->total_sectors = dev->total_sectors;
  698. disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE;
  699. disk->id = dev->id;
  700. dev->ref++;
  701. return GRUB_ERR_NONE;
  702. }
  703. static void
  704. grub_cryptodisk_close (grub_disk_t disk)
  705. {
  706. grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data;
  707. grub_dprintf ("cryptodisk", "Closing disk\n");
  708. dev->ref--;
  709. if (dev->ref != 0)
  710. return;
  711. #ifdef GRUB_UTIL
  712. if (dev->cheat)
  713. {
  714. grub_util_fd_close (dev->cheat_fd);
  715. dev->cheat_fd = GRUB_UTIL_FD_INVALID;
  716. }
  717. #endif
  718. grub_disk_close (dev->source_disk);
  719. dev->source_disk = NULL;
  720. }
  721. static grub_err_t
  722. grub_cryptodisk_read (grub_disk_t disk, grub_disk_addr_t sector,
  723. grub_size_t size, char *buf)
  724. {
  725. grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data;
  726. grub_err_t err;
  727. gcry_err_code_t gcry_err;
  728. #ifdef GRUB_UTIL
  729. if (dev->cheat)
  730. {
  731. int r;
  732. r = grub_util_fd_seek (dev->cheat_fd, sector << disk->log_sector_size);
  733. if (r)
  734. return grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot seek `%s': %s"),
  735. dev->cheat, grub_util_fd_strerror ());
  736. if (grub_util_fd_read (dev->cheat_fd, buf, size << disk->log_sector_size)
  737. != (ssize_t) (size << disk->log_sector_size))
  738. return grub_error (GRUB_ERR_READ_ERROR, N_("cannot read `%s': %s"),
  739. dev->cheat, grub_util_fd_strerror ());
  740. return GRUB_ERR_NONE;
  741. }
  742. #endif
  743. grub_dprintf ("cryptodisk",
  744. "Reading %" PRIuGRUB_SIZE " sectors from sector 0x%"
  745. PRIxGRUB_UINT64_T " with offset of %" PRIuGRUB_UINT64_T "\n",
  746. size, sector, dev->offset_sectors);
  747. err = grub_disk_read (dev->source_disk,
  748. grub_disk_from_native_sector (disk, sector + dev->offset_sectors),
  749. 0, size << disk->log_sector_size, buf);
  750. if (err)
  751. {
  752. grub_dprintf ("cryptodisk", "grub_disk_read failed with error %d\n", err);
  753. return err;
  754. }
  755. gcry_err = grub_cryptodisk_endecrypt (dev, (grub_uint8_t *) buf,
  756. size << disk->log_sector_size,
  757. sector, dev->log_sector_size, 0);
  758. return grub_crypto_gcry_error (gcry_err);
  759. }
  760. static grub_err_t
  761. grub_cryptodisk_write (grub_disk_t disk, grub_disk_addr_t sector,
  762. grub_size_t size, const char *buf)
  763. {
  764. grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data;
  765. gcry_err_code_t gcry_err;
  766. char *tmp;
  767. grub_err_t err;
  768. #ifdef GRUB_UTIL
  769. if (dev->cheat)
  770. {
  771. int r;
  772. r = grub_util_fd_seek (dev->cheat_fd, sector << disk->log_sector_size);
  773. if (r)
  774. return grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot seek `%s': %s"),
  775. dev->cheat, grub_util_fd_strerror ());
  776. if (grub_util_fd_write (dev->cheat_fd, buf, size << disk->log_sector_size)
  777. != (ssize_t) (size << disk->log_sector_size))
  778. return grub_error (GRUB_ERR_READ_ERROR, N_("cannot read `%s': %s"),
  779. dev->cheat, grub_util_fd_strerror ());
  780. return GRUB_ERR_NONE;
  781. }
  782. #endif
  783. tmp = grub_malloc (size << disk->log_sector_size);
  784. if (!tmp)
  785. return grub_errno;
  786. grub_memcpy (tmp, buf, size << disk->log_sector_size);
  787. grub_dprintf ("cryptodisk",
  788. "Writing %" PRIuGRUB_SIZE " sectors to sector 0x%"
  789. PRIxGRUB_UINT64_T " with offset of %" PRIuGRUB_UINT64_T "\n",
  790. size, sector, dev->offset_sectors);
  791. gcry_err = grub_cryptodisk_endecrypt (dev, (grub_uint8_t *) tmp,
  792. size << disk->log_sector_size,
  793. sector, disk->log_sector_size, 1);
  794. if (gcry_err)
  795. {
  796. grub_free (tmp);
  797. return grub_crypto_gcry_error (gcry_err);
  798. }
  799. /* Since ->write was called so disk.mod is loaded but be paranoid */
  800. sector = sector + dev->offset_sectors;
  801. if (grub_disk_write_weak)
  802. err = grub_disk_write_weak (dev->source_disk,
  803. grub_disk_from_native_sector (disk, sector),
  804. 0, size << disk->log_sector_size, tmp);
  805. else
  806. err = grub_error (GRUB_ERR_BUG, "disk.mod not loaded");
  807. grub_free (tmp);
  808. return err;
  809. }
  810. #ifdef GRUB_UTIL
  811. static grub_disk_memberlist_t
  812. grub_cryptodisk_memberlist (grub_disk_t disk)
  813. {
  814. grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data;
  815. grub_disk_memberlist_t list = NULL;
  816. list = grub_malloc (sizeof (*list));
  817. if (list)
  818. {
  819. list->disk = dev->source_disk;
  820. list->next = NULL;
  821. }
  822. return list;
  823. }
  824. #endif
  825. static void
  826. cryptodisk_cleanup (void)
  827. {
  828. #if 0
  829. grub_cryptodisk_t dev = cryptodisk_list;
  830. grub_cryptodisk_t tmp;
  831. while (dev != NULL)
  832. {
  833. grub_free (dev->source);
  834. grub_free (dev->cipher);
  835. grub_free (dev->secondary_cipher);
  836. grub_free (dev->essiv_cipher);
  837. tmp = dev->next;
  838. grub_free (dev);
  839. dev = tmp;
  840. }
  841. #endif
  842. }
  843. grub_err_t
  844. grub_cryptodisk_insert (grub_cryptodisk_t newdev, const char *name,
  845. grub_disk_t source)
  846. {
  847. newdev->source = grub_strdup (name);
  848. if (!newdev->source)
  849. return grub_errno;
  850. newdev->id = last_cryptodisk_id++;
  851. newdev->source_id = source->id;
  852. newdev->source_dev_id = source->dev->id;
  853. newdev->partition_start = grub_partition_get_start (source->partition);
  854. newdev->next = cryptodisk_list;
  855. cryptodisk_list = newdev;
  856. return GRUB_ERR_NONE;
  857. }
  858. grub_cryptodisk_t
  859. grub_cryptodisk_get_by_uuid (const char *uuid)
  860. {
  861. grub_cryptodisk_t dev;
  862. for (dev = cryptodisk_list; dev != NULL; dev = dev->next)
  863. if (grub_uuidcasecmp (dev->uuid, uuid, sizeof (dev->uuid)) == 0)
  864. return dev;
  865. return NULL;
  866. }
  867. grub_cryptodisk_t
  868. grub_cryptodisk_get_by_source_disk (grub_disk_t disk)
  869. {
  870. grub_cryptodisk_t dev;
  871. for (dev = cryptodisk_list; dev != NULL; dev = dev->next)
  872. if (dev->source_id == disk->id && dev->source_dev_id == disk->dev->id)
  873. if ((disk->partition && grub_partition_get_start (disk->partition) == dev->partition_start) ||
  874. (!disk->partition && dev->partition_start == 0))
  875. return dev;
  876. return NULL;
  877. }
  878. #ifdef GRUB_UTIL
  879. grub_err_t
  880. grub_cryptodisk_cheat_insert (grub_cryptodisk_t newdev, const char *name,
  881. grub_disk_t source, const char *cheat)
  882. {
  883. newdev->cheat = grub_strdup (cheat);
  884. newdev->source = grub_strdup (name);
  885. if (!newdev->source || !newdev->cheat)
  886. {
  887. grub_free (newdev->source);
  888. grub_free (newdev->cheat);
  889. return grub_errno;
  890. }
  891. newdev->cheat_fd = GRUB_UTIL_FD_INVALID;
  892. newdev->source_id = source->id;
  893. newdev->source_dev_id = source->dev->id;
  894. newdev->partition_start = grub_partition_get_start (source->partition);
  895. newdev->id = last_cryptodisk_id++;
  896. newdev->next = cryptodisk_list;
  897. cryptodisk_list = newdev;
  898. return GRUB_ERR_NONE;
  899. }
  900. void
  901. grub_util_cryptodisk_get_abstraction (grub_disk_t disk,
  902. void (*cb) (const char *val, void *data),
  903. void *data)
  904. {
  905. grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data;
  906. cb ("cryptodisk", data);
  907. cb (dev->modname, data);
  908. if (dev->cipher)
  909. cb (dev->cipher->cipher->modname, data);
  910. if (dev->secondary_cipher)
  911. cb (dev->secondary_cipher->cipher->modname, data);
  912. if (dev->essiv_cipher)
  913. cb (dev->essiv_cipher->cipher->modname, data);
  914. if (dev->hash)
  915. cb (dev->hash->modname, data);
  916. if (dev->essiv_hash)
  917. cb (dev->essiv_hash->modname, data);
  918. if (dev->iv_hash)
  919. cb (dev->iv_hash->modname, data);
  920. }
  921. const char *
  922. grub_util_cryptodisk_get_uuid (grub_disk_t disk)
  923. {
  924. grub_cryptodisk_t dev = (grub_cryptodisk_t) disk->data;
  925. return dev->uuid;
  926. }
  927. #endif
  928. static void
  929. cryptodisk_close (grub_cryptodisk_t dev)
  930. {
  931. grub_crypto_cipher_close (dev->cipher);
  932. grub_crypto_cipher_close (dev->secondary_cipher);
  933. grub_crypto_cipher_close (dev->essiv_cipher);
  934. grub_free (dev);
  935. }
  936. static grub_err_t
  937. cryptodisk_read_hook (grub_disk_addr_t sector, unsigned offset,
  938. unsigned length, char *buf, void *data)
  939. {
  940. cryptodisk_read_hook_ctx_t ctx = data;
  941. if (ctx->hdr_file == NULL)
  942. return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("header file not found"));
  943. if (grub_file_seek (ctx->hdr_file,
  944. ((sector - ctx->part_start) * GRUB_DISK_SECTOR_SIZE) + offset)
  945. == (grub_off_t) -1)
  946. return grub_errno;
  947. if (grub_file_read (ctx->hdr_file, buf, length) != (grub_ssize_t) length)
  948. {
  949. if (grub_errno == GRUB_ERR_NONE)
  950. grub_error (GRUB_ERR_OUT_OF_RANGE, N_("header file too small"));
  951. return grub_errno;
  952. }
  953. return GRUB_ERR_NONE;
  954. }
  955. static grub_cryptodisk_t
  956. grub_cryptodisk_scan_device_real (const char *name,
  957. grub_disk_t source,
  958. grub_cryptomount_args_t cargs)
  959. {
  960. grub_err_t ret = GRUB_ERR_NONE;
  961. grub_cryptodisk_t dev;
  962. grub_cryptodisk_dev_t cr;
  963. int i;
  964. struct cryptodisk_read_hook_ctx read_hook_data = {0};
  965. int askpass = 0;
  966. char *part = NULL;
  967. dev = grub_cryptodisk_get_by_source_disk (source);
  968. if (dev)
  969. return dev;
  970. if (cargs->hdr_file != NULL)
  971. {
  972. /*
  973. * Set read hook to read header from a file instead of the source disk.
  974. * Disk read hooks are executed after the data has been read from the
  975. * disk. This is okay, because the read hook is given the read buffer
  976. * before its sent back to the caller. In this case, the hook can then
  977. * overwrite the data read from the disk device with data from the
  978. * header file sent in as the read hook data. This is transparent to the
  979. * read caller. Since the callers of this function have just opened the
  980. * source disk, there are no current read hooks, so there's no need to
  981. * save/restore them nor consider if they should be called or not.
  982. *
  983. * This hook assumes that the header is at the start of the volume, which
  984. * is not the case for some formats (eg. GELI). It also can only be used
  985. * with formats where the detached header file can be written to the
  986. * first blocks of the volume and the volume could still be unlocked.
  987. * So the header file can not be formatted differently from the on-disk
  988. * header. If these assumpts are not met, detached header file processing
  989. * must be specially handled in the cryptodisk backend module.
  990. *
  991. * This hook needs only be set once and will be called potentially many
  992. * times by a backend. This is fine because of the assumptions mentioned
  993. * and the read hook reads from absolute offsets and is stateless.
  994. */
  995. read_hook_data.part_start = grub_partition_get_start (source->partition);
  996. read_hook_data.hdr_file = cargs->hdr_file;
  997. source->read_hook = cryptodisk_read_hook;
  998. source->read_hook_data = (void *) &read_hook_data;
  999. }
  1000. FOR_CRYPTODISK_DEVS (cr)
  1001. {
  1002. /*
  1003. * Loop through each cryptodisk backend that is registered (ie. loaded).
  1004. * If the scan returns NULL, then the backend being tested does not
  1005. * recognize the source disk, so move on to the next backend.
  1006. */
  1007. dev = cr->scan (source, cargs);
  1008. if (grub_errno)
  1009. goto error_no_close;
  1010. if (!dev)
  1011. continue;
  1012. break;
  1013. }
  1014. if (dev == NULL)
  1015. {
  1016. grub_error (GRUB_ERR_BAD_MODULE,
  1017. "no cryptodisk module can handle this device");
  1018. goto error_no_close;
  1019. }
  1020. if (cargs->protectors)
  1021. {
  1022. for (i = 0; cargs->protectors[i]; i++)
  1023. {
  1024. if (cargs->key_cache[i].invalid)
  1025. continue;
  1026. if (cargs->key_cache[i].key == NULL)
  1027. {
  1028. ret = grub_key_protector_recover_key (cargs->protectors[i],
  1029. &cargs->key_cache[i].key,
  1030. &cargs->key_cache[i].key_len);
  1031. if (ret != GRUB_ERR_NONE)
  1032. {
  1033. if (grub_errno)
  1034. {
  1035. grub_print_error ();
  1036. grub_errno = GRUB_ERR_NONE;
  1037. }
  1038. grub_dprintf ("cryptodisk",
  1039. "failed to recover a key from key protector "
  1040. "%s, will not try it again for any other "
  1041. "disks, if any, during this invocation of "
  1042. "cryptomount\n",
  1043. cargs->protectors[i]);
  1044. cargs->key_cache[i].invalid = 1;
  1045. continue;
  1046. }
  1047. }
  1048. cargs->key_data = cargs->key_cache[i].key;
  1049. cargs->key_len = cargs->key_cache[i].key_len;
  1050. ret = cr->recover_key (source, dev, cargs);
  1051. if (ret != GRUB_ERR_NONE)
  1052. {
  1053. /* Reset key data to trigger the passphrase prompt later */
  1054. cargs->key_data = NULL;
  1055. cargs->key_len = 0;
  1056. part = grub_partition_get_name (source->partition);
  1057. grub_dprintf ("cryptodisk",
  1058. "recovered a key from key protector %s but it "
  1059. "failed to unlock %s%s%s (%s)\n",
  1060. cargs->protectors[i], source->name,
  1061. source->partition != NULL ? "," : "",
  1062. part != NULL ? part : N_("UNKNOWN"), dev->uuid);
  1063. grub_free (part);
  1064. continue;
  1065. }
  1066. else
  1067. {
  1068. ret = grub_cryptodisk_insert (dev, name, source);
  1069. if (ret != GRUB_ERR_NONE)
  1070. goto error;
  1071. goto cleanup;
  1072. }
  1073. }
  1074. part = grub_partition_get_name (source->partition);
  1075. grub_error (GRUB_ERR_ACCESS_DENIED,
  1076. N_("no key protector provided a usable key for %s%s%s (%s)"),
  1077. source->name, source->partition != NULL ? "," : "",
  1078. part != NULL ? part : N_("UNKNOWN"), dev->uuid);
  1079. grub_free (part);
  1080. }
  1081. if (cargs->key_len)
  1082. {
  1083. ret = cr->recover_key (source, dev, cargs);
  1084. if (ret != GRUB_ERR_NONE)
  1085. goto error;
  1086. }
  1087. else
  1088. {
  1089. /* Get the passphrase from the user, if no key data. */
  1090. unsigned long tries = 3;
  1091. const char *tries_env;
  1092. /*
  1093. * Print the error from key protectors and clear grub_errno.
  1094. *
  1095. * Since '--protector' cannot coexist with '--password' and
  1096. * '--key-file', in case key protectors fail, only
  1097. * "cargs->key_len == 0" is expected, so cryptomount falls back
  1098. * here to request the passphrase.
  1099. *
  1100. * To avoid the error from key protectors stops the further code,
  1101. * print the error to notify the user why key protectors fail and
  1102. * clear grub_errno to have a fresh start.
  1103. */
  1104. if (grub_errno != GRUB_ERR_NONE)
  1105. {
  1106. grub_print_error ();
  1107. grub_errno = GRUB_ERR_NONE;
  1108. }
  1109. askpass = 1;
  1110. cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE);
  1111. if (cargs->key_data == NULL)
  1112. goto error_no_close;
  1113. tries_env = grub_env_get ("cryptodisk_passphrase_tries");
  1114. if (tries_env != NULL && tries_env[0] != '\0')
  1115. {
  1116. unsigned long tries_env_val;
  1117. const char *p;
  1118. tries_env_val = grub_strtoul (tries_env, &p, 0);
  1119. if (*p == '\0' && tries_env_val != ~0UL)
  1120. tries = tries_env_val;
  1121. else
  1122. grub_printf_ (N_("Invalid cryptodisk_passphrase_tries value `%s'. Defaulting to %lu.\n"),
  1123. tries_env,
  1124. tries);
  1125. }
  1126. for (; tries > 0; tries--)
  1127. {
  1128. part = grub_partition_get_name (source->partition);
  1129. grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
  1130. source->partition != NULL ? "," : "",
  1131. part != NULL ? part : N_("UNKNOWN"),
  1132. dev->uuid);
  1133. grub_free (part);
  1134. if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE))
  1135. {
  1136. grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied");
  1137. goto error;
  1138. }
  1139. cargs->key_len = grub_strlen ((char *) cargs->key_data);
  1140. ret = cr->recover_key (source, dev, cargs);
  1141. if (ret == GRUB_ERR_NONE)
  1142. break;
  1143. if (ret != GRUB_ERR_ACCESS_DENIED || tries == 1)
  1144. goto error;
  1145. grub_puts_ (N_("Invalid passphrase."));
  1146. /*
  1147. * Since recover_key() calls a function that returns grub_errno,
  1148. * a leftover error value from a previously rejected passphrase
  1149. * will trigger a phantom failure. We therefore clear it before
  1150. * trying a new passphrase.
  1151. */
  1152. grub_errno = GRUB_ERR_NONE;
  1153. }
  1154. }
  1155. ret = grub_cryptodisk_insert (dev, name, source);
  1156. if (ret != GRUB_ERR_NONE)
  1157. goto error;
  1158. goto cleanup;
  1159. error:
  1160. cryptodisk_close (dev);
  1161. error_no_close:
  1162. dev = NULL;
  1163. cleanup:
  1164. if (cargs->hdr_file != NULL)
  1165. source->read_hook = NULL;
  1166. if (askpass)
  1167. {
  1168. cargs->key_len = 0;
  1169. grub_free (cargs->key_data);
  1170. }
  1171. return dev;
  1172. }
  1173. #ifdef GRUB_UTIL
  1174. #include <grub/util/misc.h>
  1175. grub_err_t
  1176. grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat)
  1177. {
  1178. grub_err_t err;
  1179. grub_cryptodisk_t dev;
  1180. grub_cryptodisk_dev_t cr;
  1181. grub_disk_t source;
  1182. struct grub_cryptomount_args cargs = {0};
  1183. /* Try to open disk. */
  1184. source = grub_disk_open (sourcedev);
  1185. if (!source)
  1186. return grub_errno;
  1187. dev = grub_cryptodisk_get_by_source_disk (source);
  1188. if (dev)
  1189. {
  1190. grub_disk_close (source);
  1191. return GRUB_ERR_NONE;
  1192. }
  1193. FOR_CRYPTODISK_DEVS (cr)
  1194. {
  1195. dev = cr->scan (source, &cargs);
  1196. if (grub_errno)
  1197. return grub_errno;
  1198. if (!dev)
  1199. continue;
  1200. grub_util_info ("cheatmounted %s (%s) at %s", sourcedev, dev->modname,
  1201. cheat);
  1202. err = grub_cryptodisk_cheat_insert (dev, sourcedev, source, cheat);
  1203. grub_disk_close (source);
  1204. if (err)
  1205. grub_free (dev);
  1206. return GRUB_ERR_NONE;
  1207. }
  1208. grub_disk_close (source);
  1209. return GRUB_ERR_NONE;
  1210. }
  1211. #endif
  1212. static int
  1213. grub_cryptodisk_scan_device (const char *name,
  1214. void *data)
  1215. {
  1216. int ret = 0;
  1217. grub_disk_t source;
  1218. grub_cryptodisk_t dev;
  1219. grub_cryptomount_args_t cargs = data;
  1220. grub_errno = GRUB_ERR_NONE;
  1221. /* Try to open disk. */
  1222. source = grub_disk_open (name);
  1223. if (!source)
  1224. {
  1225. grub_print_error ();
  1226. return 0;
  1227. }
  1228. dev = grub_cryptodisk_scan_device_real (name, source, cargs);
  1229. if (dev)
  1230. {
  1231. ret = (cargs->search_uuid != NULL
  1232. && grub_uuidcasecmp (cargs->search_uuid, dev->uuid, sizeof (dev->uuid)) == 0);
  1233. goto cleanup;
  1234. }
  1235. /*
  1236. * Do not print error when err is GRUB_ERR_BAD_MODULE to avoid many unhelpful
  1237. * error messages.
  1238. */
  1239. if (grub_errno == GRUB_ERR_BAD_MODULE)
  1240. grub_error_pop ();
  1241. if (cargs->search_uuid != NULL)
  1242. /* Push error onto stack to save for cryptomount. */
  1243. grub_error_push ();
  1244. else
  1245. grub_print_error ();
  1246. cleanup:
  1247. grub_disk_close (source);
  1248. return ret;
  1249. }
  1250. static void
  1251. grub_cryptodisk_clear_key_cache (struct grub_cryptomount_args *cargs)
  1252. {
  1253. int i;
  1254. if (cargs->key_cache == NULL || cargs->protectors == NULL)
  1255. return;
  1256. for (i = 0; cargs->protectors[i]; i++)
  1257. {
  1258. if (cargs->key_cache[i].key)
  1259. grub_memset (cargs->key_cache[i].key, 0, cargs->key_cache[i].key_len);
  1260. grub_free (cargs->key_cache[i].key);
  1261. }
  1262. grub_free (cargs->key_cache);
  1263. }
  1264. static grub_err_t
  1265. grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
  1266. {
  1267. struct grub_arg_list *state = ctxt->state;
  1268. struct grub_cryptomount_args cargs = {0};
  1269. if (argc < 1 && !state[OPTION_ALL].set && !state[OPTION_BOOT].set)
  1270. return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
  1271. if (grub_cryptodisk_list == NULL)
  1272. return grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk modules loaded");
  1273. if (state[OPTION_PASSWORD].set && state[OPTION_PROTECTOR].set) /* password and key protector */
  1274. return grub_error (GRUB_ERR_BAD_ARGUMENT,
  1275. "a password and a key protector cannot both be set");
  1276. if (state[OPTION_KEYFILE].set && state[OPTION_PROTECTOR].set) /* key file and key protector */
  1277. return grub_error (GRUB_ERR_BAD_ARGUMENT,
  1278. "a key file and a key protector cannot both be set");
  1279. if (state[OPTION_PASSWORD].set) /* password */
  1280. {
  1281. cargs.key_data = (grub_uint8_t *) state[OPTION_PASSWORD].arg;
  1282. cargs.key_len = grub_strlen (state[OPTION_PASSWORD].arg);
  1283. }
  1284. if (state[OPTION_KEYFILE].set) /* keyfile */
  1285. {
  1286. const char *p = NULL;
  1287. grub_file_t keyfile;
  1288. unsigned long long keyfile_offset = 0, keyfile_size = 0;
  1289. if (state[OPTION_KEYFILE_OFFSET].set) /* keyfile-offset */
  1290. {
  1291. grub_errno = GRUB_ERR_NONE;
  1292. keyfile_offset = grub_strtoull (state[OPTION_KEYFILE_OFFSET].arg, &p, 0);
  1293. if (state[OPTION_KEYFILE_OFFSET].arg[0] == '\0' || *p != '\0')
  1294. return grub_error (grub_errno,
  1295. N_("non-numeric or invalid keyfile offset `%s'"),
  1296. state[OPTION_KEYFILE_OFFSET].arg);
  1297. }
  1298. if (state[OPTION_KEYFILE_SIZE].set) /* keyfile-size */
  1299. {
  1300. grub_errno = GRUB_ERR_NONE;
  1301. keyfile_size = grub_strtoull (state[OPTION_KEYFILE_SIZE].arg, &p, 0);
  1302. if (state[OPTION_KEYFILE_SIZE].arg[0] == '\0' || *p != '\0')
  1303. return grub_error (grub_errno,
  1304. N_("non-numeric or invalid keyfile size `%s'"),
  1305. state[OPTION_KEYFILE_SIZE].arg);
  1306. if (keyfile_size == 0)
  1307. return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("key file size is 0"));
  1308. if (keyfile_size > GRUB_CRYPTODISK_MAX_KEYFILE_SIZE)
  1309. return grub_error (GRUB_ERR_OUT_OF_RANGE,
  1310. N_("key file size exceeds maximum (%d)"),
  1311. GRUB_CRYPTODISK_MAX_KEYFILE_SIZE);
  1312. }
  1313. keyfile = grub_file_open (state[OPTION_KEYFILE].arg,
  1314. GRUB_FILE_TYPE_CRYPTODISK_ENCRYPTION_KEY);
  1315. if (keyfile == NULL)
  1316. return grub_errno;
  1317. if (keyfile_offset > keyfile->size)
  1318. return grub_error (GRUB_ERR_OUT_OF_RANGE,
  1319. N_("Keyfile offset, %llu, is greater than "
  1320. "keyfile size, %llu"),
  1321. keyfile_offset, (unsigned long long) keyfile->size);
  1322. if (grub_file_seek (keyfile, (grub_off_t) keyfile_offset) == (grub_off_t) -1)
  1323. return grub_errno;
  1324. if (keyfile_size != 0)
  1325. {
  1326. if (keyfile_size > (keyfile->size - keyfile_offset))
  1327. return grub_error (GRUB_ERR_FILE_READ_ERROR,
  1328. N_("keyfile is too small: requested %llu bytes,"
  1329. " but the file only has %" PRIuGRUB_UINT64_T
  1330. " bytes left at offset %llu"),
  1331. keyfile_size,
  1332. (grub_off_t) (keyfile->size - keyfile_offset),
  1333. keyfile_offset);
  1334. cargs.key_len = keyfile_size;
  1335. }
  1336. else
  1337. cargs.key_len = keyfile->size - keyfile_offset;
  1338. cargs.key_data = grub_malloc (cargs.key_len);
  1339. if (cargs.key_data == NULL)
  1340. return GRUB_ERR_OUT_OF_MEMORY;
  1341. if (grub_file_read (keyfile, cargs.key_data, cargs.key_len) != (grub_ssize_t) cargs.key_len)
  1342. return grub_error (GRUB_ERR_FILE_READ_ERROR, (N_("failed to read key file")));
  1343. }
  1344. if (state[OPTION_HEADER].set) /* header */
  1345. {
  1346. if (state[OPTION_UUID].set)
  1347. return grub_error (GRUB_ERR_BAD_ARGUMENT,
  1348. N_("cannot use UUID lookup with detached header"));
  1349. cargs.hdr_file = grub_file_open (state[OPTION_HEADER].arg,
  1350. GRUB_FILE_TYPE_CRYPTODISK_DETACHED_HEADER);
  1351. if (cargs.hdr_file == NULL)
  1352. return grub_errno;
  1353. }
  1354. if (state[OPTION_PROTECTOR].set) /* key protector(s) */
  1355. {
  1356. cargs.key_cache = grub_zalloc (state[OPTION_PROTECTOR].set * sizeof (*cargs.key_cache));
  1357. if (cargs.key_cache == NULL)
  1358. return grub_error (GRUB_ERR_OUT_OF_MEMORY,
  1359. "no memory for key protector key cache");
  1360. cargs.protectors = state[OPTION_PROTECTOR].args;
  1361. }
  1362. if (state[OPTION_UUID].set) /* uuid */
  1363. {
  1364. int found_uuid;
  1365. grub_cryptodisk_t dev;
  1366. dev = grub_cryptodisk_get_by_uuid (args[0]);
  1367. if (dev)
  1368. {
  1369. grub_cryptodisk_clear_key_cache (&cargs);
  1370. grub_dprintf ("cryptodisk",
  1371. "already mounted as crypto%lu\n", dev->id);
  1372. return GRUB_ERR_NONE;
  1373. }
  1374. cargs.check_boot = state[OPTION_BOOT].set;
  1375. cargs.search_uuid = args[0];
  1376. found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
  1377. grub_cryptodisk_clear_key_cache (&cargs);
  1378. if (found_uuid)
  1379. return GRUB_ERR_NONE;
  1380. else if (grub_errno == GRUB_ERR_NONE)
  1381. {
  1382. /*
  1383. * Try to pop the next error on the stack. If there is not one, then
  1384. * no device matched the given UUID.
  1385. */
  1386. grub_error_pop ();
  1387. if (grub_errno == GRUB_ERR_NONE)
  1388. return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such cryptodisk found, perhaps a needed disk or cryptodisk module is not loaded");
  1389. }
  1390. return grub_errno;
  1391. }
  1392. else if (state[OPTION_ALL].set || (argc == 0 && state[OPTION_BOOT].set)) /* -a|-b */
  1393. {
  1394. cargs.check_boot = state[OPTION_BOOT].set;
  1395. grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
  1396. grub_cryptodisk_clear_key_cache (&cargs);
  1397. return GRUB_ERR_NONE;
  1398. }
  1399. else
  1400. {
  1401. grub_disk_t disk;
  1402. grub_cryptodisk_t dev;
  1403. char *diskname;
  1404. char *disklast = NULL;
  1405. grub_size_t len;
  1406. cargs.check_boot = state[OPTION_BOOT].set;
  1407. diskname = args[0];
  1408. len = grub_strlen (diskname);
  1409. if (len && diskname[0] == '(' && diskname[len - 1] == ')')
  1410. {
  1411. disklast = &diskname[len - 1];
  1412. *disklast = '\0';
  1413. diskname++;
  1414. }
  1415. disk = grub_disk_open (diskname);
  1416. if (!disk)
  1417. {
  1418. grub_cryptodisk_clear_key_cache (&cargs);
  1419. if (disklast)
  1420. *disklast = ')';
  1421. return grub_errno;
  1422. }
  1423. dev = grub_cryptodisk_get_by_source_disk (disk);
  1424. if (dev)
  1425. {
  1426. grub_dprintf ("cryptodisk", "already mounted as crypto%lu\n", dev->id);
  1427. grub_disk_close (disk);
  1428. grub_cryptodisk_clear_key_cache (&cargs);
  1429. if (disklast)
  1430. *disklast = ')';
  1431. return GRUB_ERR_NONE;
  1432. }
  1433. dev = grub_cryptodisk_scan_device_real (diskname, disk, &cargs);
  1434. grub_cryptodisk_clear_key_cache (&cargs);
  1435. grub_disk_close (disk);
  1436. if (disklast)
  1437. *disklast = ')';
  1438. return (dev == NULL) ? grub_errno : GRUB_ERR_NONE;
  1439. }
  1440. }
  1441. static struct grub_disk_dev grub_cryptodisk_dev = {
  1442. .name = "cryptodisk",
  1443. .id = GRUB_DISK_DEVICE_CRYPTODISK_ID,
  1444. .disk_iterate = grub_cryptodisk_iterate,
  1445. .disk_open = grub_cryptodisk_open,
  1446. .disk_close = grub_cryptodisk_close,
  1447. .disk_read = grub_cryptodisk_read,
  1448. .disk_write = grub_cryptodisk_write,
  1449. #ifdef GRUB_UTIL
  1450. .disk_memberlist = grub_cryptodisk_memberlist,
  1451. #endif
  1452. .next = 0
  1453. };
  1454. static char
  1455. hex (grub_uint8_t val)
  1456. {
  1457. if (val < 10)
  1458. return '0' + val;
  1459. return 'a' + val - 10;
  1460. }
  1461. /* Open a file named NAME and initialize FILE. */
  1462. static char *
  1463. luks_script_get (grub_size_t *sz)
  1464. {
  1465. grub_cryptodisk_t i;
  1466. grub_size_t size = 0;
  1467. char *ptr, *ret;
  1468. *sz = 0;
  1469. for (i = cryptodisk_list; i != NULL; i = i->next)
  1470. if (grub_strcmp (i->modname, "luks") == 0 ||
  1471. grub_strcmp (i->modname, "luks2") == 0)
  1472. {
  1473. size += grub_strlen (i->modname);
  1474. size += sizeof ("_mount");
  1475. size += grub_strlen (i->uuid);
  1476. size += grub_strlen (i->cipher->cipher->name);
  1477. /*
  1478. * Add space in the line for (in order) spaces, cipher mode, cipher IV
  1479. * mode, sector offset, sector size and the trailing newline. This is
  1480. * an upper bound on the size of this data. There are 15 extra bytes
  1481. * in an earlier version of this code that are unaccounted for. It is
  1482. * left in the calculations in case it is needed. At worst, its short-
  1483. * lived wasted space.
  1484. */
  1485. size += 5 + 5 + 8 + 20 + 6 + 1 + 15;
  1486. if (i->essiv_hash)
  1487. size += grub_strlen (i->essiv_hash->name);
  1488. size += i->keysize * 2;
  1489. }
  1490. ret = grub_malloc (size + 1);
  1491. if (!ret)
  1492. return 0;
  1493. ptr = ret;
  1494. for (i = cryptodisk_list; i != NULL; i = i->next)
  1495. if (grub_strcmp (i->modname, "luks") == 0 ||
  1496. grub_strcmp (i->modname, "luks2") == 0)
  1497. {
  1498. unsigned j;
  1499. const char *iptr;
  1500. ptr = grub_stpcpy (ptr, i->modname);
  1501. ptr = grub_stpcpy (ptr, "_mount ");
  1502. ptr = grub_stpcpy (ptr, i->uuid);
  1503. *ptr++ = ' ';
  1504. ptr += grub_snprintf (ptr, 21, "%" PRIxGRUB_OFFSET, i->offset_sectors);
  1505. *ptr++ = ' ';
  1506. ptr += grub_snprintf (ptr, 7, "%u", 1 << i->log_sector_size);
  1507. *ptr++ = ' ';
  1508. for (iptr = i->cipher->cipher->name; *iptr; iptr++)
  1509. *ptr++ = grub_tolower (*iptr);
  1510. switch (i->mode)
  1511. {
  1512. case GRUB_CRYPTODISK_MODE_ECB:
  1513. ptr = grub_stpcpy (ptr, "-ecb");
  1514. break;
  1515. case GRUB_CRYPTODISK_MODE_CBC:
  1516. ptr = grub_stpcpy (ptr, "-cbc");
  1517. break;
  1518. case GRUB_CRYPTODISK_MODE_PCBC:
  1519. ptr = grub_stpcpy (ptr, "-pcbc");
  1520. break;
  1521. case GRUB_CRYPTODISK_MODE_XTS:
  1522. ptr = grub_stpcpy (ptr, "-xts");
  1523. break;
  1524. case GRUB_CRYPTODISK_MODE_LRW:
  1525. ptr = grub_stpcpy (ptr, "-lrw");
  1526. break;
  1527. }
  1528. switch (i->mode_iv)
  1529. {
  1530. case GRUB_CRYPTODISK_MODE_IV_NULL:
  1531. ptr = grub_stpcpy (ptr, "-null");
  1532. break;
  1533. case GRUB_CRYPTODISK_MODE_IV_PLAIN:
  1534. ptr = grub_stpcpy (ptr, "-plain");
  1535. break;
  1536. case GRUB_CRYPTODISK_MODE_IV_PLAIN64:
  1537. ptr = grub_stpcpy (ptr, "-plain64");
  1538. break;
  1539. case GRUB_CRYPTODISK_MODE_IV_BENBI:
  1540. ptr = grub_stpcpy (ptr, "-benbi");
  1541. break;
  1542. case GRUB_CRYPTODISK_MODE_IV_ESSIV:
  1543. ptr = grub_stpcpy (ptr, "-essiv:");
  1544. ptr = grub_stpcpy (ptr, i->essiv_hash->name);
  1545. break;
  1546. case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64:
  1547. case GRUB_CRYPTODISK_MODE_IV_BYTECOUNT64_HASH:
  1548. break;
  1549. }
  1550. *ptr++ = ' ';
  1551. for (j = 0; j < i->keysize; j++)
  1552. {
  1553. *ptr++ = hex (i->key[j] >> 4);
  1554. *ptr++ = hex (i->key[j] & 0xf);
  1555. }
  1556. *ptr++ = '\n';
  1557. }
  1558. *ptr = '\0';
  1559. *sz = ptr - ret;
  1560. return ret;
  1561. }
  1562. struct grub_procfs_entry luks_script =
  1563. {
  1564. .name = "luks_script",
  1565. .get_contents = luks_script_get
  1566. };
  1567. static grub_extcmd_t cmd;
  1568. GRUB_MOD_INIT (cryptodisk)
  1569. {
  1570. grub_disk_dev_register (&grub_cryptodisk_dev);
  1571. cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0,
  1572. N_("[ [-p password] | [-k keyfile"
  1573. " [-O keyoffset] [-S keysize] ] ] [-H file]"
  1574. " [-P protector [-P protector ...]]"
  1575. " <SOURCE|-u UUID|-a|-b>"),
  1576. N_("Mount a crypto device."), options);
  1577. grub_procfs_register ("luks_script", &luks_script);
  1578. }
  1579. GRUB_MOD_FINI (cryptodisk)
  1580. {
  1581. grub_disk_dev_unregister (&grub_cryptodisk_dev);
  1582. cryptodisk_cleanup ();
  1583. grub_unregister_extcmd (cmd);
  1584. grub_procfs_unregister (&luks_script);
  1585. }