0004-Cryptomount-support-plain-dm-crypt.patch 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. From c584bacaad58facb9124df26f98fff2542f7237a Mon Sep 17 00:00:00 2001
  2. From: John Lane <john@lane.uk.net>
  3. Date: Fri, 26 Jun 2015 22:09:52 +0100
  4. Subject: [PATCH 4/5] Cryptomount support plain dm-crypt
  5. ---
  6. grub-core/disk/cryptodisk.c | 298 +++++++++++++++++++++++++++++++++++++++++++-
  7. grub-core/disk/luks.c | 195 +----------------------------
  8. include/grub/cryptodisk.h | 8 ++
  9. 3 files changed, 310 insertions(+), 191 deletions(-)
  10. diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
  11. index a27e70c..cd5cfc9 100644
  12. --- a/grub-core/disk/cryptodisk.c
  13. +++ b/grub-core/disk/cryptodisk.c
  14. @@ -44,6 +44,12 @@ static const struct grub_arg_option options[] =
  15. {"keyfile", 'k', 0, N_("Key file"), 0, ARG_TYPE_STRING},
  16. {"keyfile-offset", 'O', 0, N_("Key file offset (bytes)"), 0, ARG_TYPE_INT},
  17. {"keyfile-size", 'S', 0, N_("Key file data size (bytes)"), 0, ARG_TYPE_INT},
  18. + {"plain", 'p', 0, N_("Plain (no LUKS header)"), 0, ARG_TYPE_NONE},
  19. + {"cipher", 'c', 0, N_("Plain mode cipher"), 0, ARG_TYPE_STRING},
  20. + {"digest", 'd', 0, N_("Plain mode passphrase digest (hash)"), 0, ARG_TYPE_STRING},
  21. + {"offset", 'o', 0, N_("Plain mode data sector offset"), 0, ARG_TYPE_INT},
  22. + {"size", 's', 0, N_("Size of raw device (sectors, defaults to whole device)"), 0, ARG_TYPE_INT},
  23. + {"key-size", 'K', 0, N_("Set key size (bits)"), 0, ARG_TYPE_INT},
  24. {0, 0, 0, 0, 0, 0}
  25. };
  26. @@ -927,6 +933,48 @@ grub_cryptodisk_scan_device (const char *name,
  27. return have_it && search_uuid ? 1 : 0;
  28. }
  29. +/* Hashes a passphrase into a key and stores it with cipher. */
  30. +static gcry_err_code_t
  31. +set_passphrase (grub_cryptodisk_t dev, grub_size_t keysize, const char *passphrase)
  32. +{
  33. + grub_uint8_t derived_hash[GRUB_CRYPTODISK_MAX_KEYLEN * 2], *dh = derived_hash;
  34. + char *p;
  35. + unsigned int round, i;
  36. + unsigned int len, size;
  37. +
  38. + /* Need no passphrase if there's no key */
  39. + if (keysize == 0)
  40. + return GPG_ERR_INV_KEYLEN;
  41. +
  42. + /* Hack to support the "none" hash */
  43. + if (dev->hash)
  44. + len = dev->hash->mdlen;
  45. + else
  46. + len = grub_strlen (passphrase);
  47. +
  48. + if (keysize > GRUB_CRYPTODISK_MAX_KEYLEN || len > GRUB_CRYPTODISK_MAX_KEYLEN)
  49. + return GPG_ERR_INV_KEYLEN;
  50. +
  51. + p = grub_malloc (grub_strlen (passphrase) + 2 + keysize / len);
  52. + if (!p)
  53. + return grub_errno;
  54. +
  55. + for (round = 0, size = keysize; size; round++, dh += len, size -= len)
  56. + {
  57. + for (i = 0; i < round; i++)
  58. + p[i] = 'A';
  59. +
  60. + grub_strcpy (p + i, passphrase);
  61. +
  62. + if (len > size)
  63. + len = size;
  64. +
  65. + grub_crypto_hash (dev->hash, dh, p, grub_strlen (p));
  66. + }
  67. +
  68. + return grub_cryptodisk_setkey (dev, derived_hash, keysize);
  69. +}
  70. +
  71. static grub_err_t
  72. grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
  73. {
  74. @@ -1046,7 +1094,63 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
  75. return GRUB_ERR_NONE;
  76. }
  77. - err = grub_cryptodisk_scan_device_real (args[0], disk);
  78. + if (state[7].set) /* Plain mode */
  79. + {
  80. + char *cipher;
  81. + char *mode;
  82. + char *digest;
  83. + int offset, size, key_size;
  84. +
  85. + cipher = grub_strdup (state[8].set ? state[8].arg : GRUB_CRYPTODISK_PLAIN_CIPHER);
  86. + digest = grub_strdup (state[9].set ? state[9].arg : GRUB_CRYPTODISK_PLAIN_DIGEST);
  87. + offset = state[10].set ? grub_strtoul (state[10].arg, 0, 0) : 0;
  88. + size = state[11].set ? grub_strtoul (state[11].arg, 0, 0) : 0;
  89. + key_size = ( state[12].set ? grub_strtoul (state[12].arg, 0, 0) \
  90. + : GRUB_CRYPTODISK_PLAIN_KEYSIZE ) / 8;
  91. +
  92. + /* no strtok, do it manually */
  93. + mode = grub_strchr(cipher,'-');
  94. + if (!mode)
  95. + return GRUB_ERR_BAD_ARGUMENT;
  96. + else
  97. + *mode++ = 0;
  98. +
  99. + dev = grub_cryptodisk_create (disk, NULL, cipher, mode, digest);
  100. +
  101. + dev->offset = offset;
  102. + if (size) dev->total_length = size;
  103. +
  104. + if (key)
  105. + {
  106. + err = grub_cryptodisk_setkey (dev, key, key_size);
  107. + if (err)
  108. + return err;
  109. + }
  110. + else
  111. + {
  112. + char passphrase[GRUB_CRYPTODISK_MAX_PASSPHRASE] = "";
  113. +
  114. + grub_printf_ (N_("Enter passphrase for %s: "), diskname);
  115. + if (!grub_password_get (passphrase, GRUB_CRYPTODISK_MAX_PASSPHRASE))
  116. + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied");
  117. +
  118. + err = set_passphrase (dev, key_size, passphrase);
  119. + if (err)
  120. + {
  121. + grub_crypto_cipher_close (dev->cipher);
  122. + return err;
  123. + }
  124. + }
  125. +
  126. + grub_cryptodisk_insert (dev, diskname, disk);
  127. +
  128. + grub_free (cipher);
  129. + grub_free (digest);
  130. +
  131. + err = GRUB_ERR_NONE;
  132. + }
  133. + else
  134. + err = grub_cryptodisk_scan_device_real (args[0], disk);
  135. grub_disk_close (disk);
  136. @@ -1177,13 +1281,203 @@ struct grub_procfs_entry luks_script =
  137. .get_contents = luks_script_get
  138. };
  139. +grub_cryptodisk_t
  140. +grub_cryptodisk_create (grub_disk_t disk, char *uuid,
  141. + char *ciphername, char *ciphermode, char *hashspec)
  142. +{
  143. + grub_cryptodisk_t newdev;
  144. + char *cipheriv = NULL;
  145. + grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL;
  146. + grub_crypto_cipher_handle_t essiv_cipher = NULL;
  147. + const gcry_md_spec_t *hash = NULL, *essiv_hash = NULL;
  148. + const struct gcry_cipher_spec *ciph;
  149. + grub_cryptodisk_mode_t mode;
  150. + grub_cryptodisk_mode_iv_t mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64;
  151. + int benbi_log = 0;
  152. +
  153. + if (!uuid)
  154. + uuid = (char*)"00000000000000000000000000000000";
  155. +
  156. + ciph = grub_crypto_lookup_cipher_by_name (ciphername);
  157. + if (!ciph)
  158. + {
  159. + grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s isn't available",
  160. + ciphername);
  161. + return NULL;
  162. + }
  163. +
  164. + /* Configure the cipher used for the bulk data. */
  165. + cipher = grub_crypto_cipher_open (ciph);
  166. + if (!cipher)
  167. + return NULL;
  168. +
  169. + /* Configure the cipher mode. */
  170. + if (grub_strcmp (ciphermode, "ecb") == 0)
  171. + {
  172. + mode = GRUB_CRYPTODISK_MODE_ECB;
  173. + mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
  174. + cipheriv = NULL;
  175. + }
  176. + else if (grub_strcmp (ciphermode, "plain") == 0)
  177. + {
  178. + mode = GRUB_CRYPTODISK_MODE_CBC;
  179. + mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
  180. + cipheriv = NULL;
  181. + }
  182. + else if (grub_memcmp (ciphermode, "cbc-", sizeof ("cbc-") - 1) == 0)
  183. + {
  184. + mode = GRUB_CRYPTODISK_MODE_CBC;
  185. + cipheriv = ciphermode + sizeof ("cbc-") - 1;
  186. + }
  187. + else if (grub_memcmp (ciphermode, "pcbc-", sizeof ("pcbc-") - 1) == 0)
  188. + {
  189. + mode = GRUB_CRYPTODISK_MODE_PCBC;
  190. + cipheriv = ciphermode + sizeof ("pcbc-") - 1;
  191. + }
  192. + else if (grub_memcmp (ciphermode, "xts-", sizeof ("xts-") - 1) == 0)
  193. + {
  194. + mode = GRUB_CRYPTODISK_MODE_XTS;
  195. + cipheriv = ciphermode + sizeof ("xts-") - 1;
  196. + secondary_cipher = grub_crypto_cipher_open (ciph);
  197. + if (!secondary_cipher)
  198. + {
  199. + grub_crypto_cipher_close (cipher);
  200. + return NULL;
  201. + }
  202. + if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
  203. + {
  204. + grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d",
  205. + cipher->cipher->blocksize);
  206. + grub_crypto_cipher_close (cipher);
  207. + grub_crypto_cipher_close (secondary_cipher);
  208. + return NULL;
  209. + }
  210. + if (secondary_cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
  211. + {
  212. + grub_crypto_cipher_close (cipher);
  213. + grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d",
  214. + secondary_cipher->cipher->blocksize);
  215. + grub_crypto_cipher_close (secondary_cipher);
  216. + return NULL;
  217. + }
  218. + }
  219. + else if (grub_memcmp (ciphermode, "lrw-", sizeof ("lrw-") - 1) == 0)
  220. + {
  221. + mode = GRUB_CRYPTODISK_MODE_LRW;
  222. + cipheriv = ciphermode + sizeof ("lrw-") - 1;
  223. + if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
  224. + {
  225. + grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported LRW block size: %d",
  226. + cipher->cipher->blocksize);
  227. + grub_crypto_cipher_close (cipher);
  228. + return NULL;
  229. + }
  230. + }
  231. + else
  232. + {
  233. + grub_crypto_cipher_close (cipher);
  234. + grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown cipher mode: %s",
  235. + ciphermode);
  236. + return NULL;
  237. + }
  238. +
  239. + if (cipheriv == NULL);
  240. + else if (grub_memcmp (cipheriv, "plain", sizeof ("plain") - 1) == 0)
  241. + mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
  242. + else if (grub_memcmp (cipheriv, "plain64", sizeof ("plain64") - 1) == 0)
  243. + mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64;
  244. + else if (grub_memcmp (cipheriv, "benbi", sizeof ("benbi") - 1) == 0)
  245. + {
  246. + if (cipher->cipher->blocksize & (cipher->cipher->blocksize - 1)
  247. + || cipher->cipher->blocksize == 0)
  248. + grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported benbi blocksize: %d",
  249. + cipher->cipher->blocksize);
  250. + /* FIXME should we return an error here? */
  251. + for (benbi_log = 0;
  252. + (cipher->cipher->blocksize << benbi_log) < GRUB_DISK_SECTOR_SIZE;
  253. + benbi_log++);
  254. + mode_iv = GRUB_CRYPTODISK_MODE_IV_BENBI;
  255. + }
  256. + else if (grub_memcmp (cipheriv, "null", sizeof ("null") - 1) == 0)
  257. + mode_iv = GRUB_CRYPTODISK_MODE_IV_NULL;
  258. + else if (grub_memcmp (cipheriv, "essiv:", sizeof ("essiv:") - 1) == 0)
  259. + {
  260. + char *hash_str = cipheriv + 6;
  261. +
  262. + mode_iv = GRUB_CRYPTODISK_MODE_IV_ESSIV;
  263. +
  264. + /* Configure the hash and cipher used for ESSIV. */
  265. + essiv_hash = grub_crypto_lookup_md_by_name (hash_str);
  266. + if (!essiv_hash)
  267. + {
  268. + grub_crypto_cipher_close (cipher);
  269. + grub_crypto_cipher_close (secondary_cipher);
  270. + grub_error (GRUB_ERR_FILE_NOT_FOUND,
  271. + "Couldn't load %s hash", hash_str);
  272. + return NULL;
  273. + }
  274. + essiv_cipher = grub_crypto_cipher_open (ciph);
  275. + if (!essiv_cipher)
  276. + {
  277. + grub_crypto_cipher_close (cipher);
  278. + grub_crypto_cipher_close (secondary_cipher);
  279. + return NULL;
  280. + }
  281. + }
  282. + else
  283. + {
  284. + grub_crypto_cipher_close (cipher);
  285. + grub_crypto_cipher_close (secondary_cipher);
  286. + grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown IV mode: %s",
  287. + cipheriv);
  288. + return NULL;
  289. + }
  290. +
  291. + /* Configure the passphrase hash (LUKS also uses AF splitter and HMAC). */
  292. + hash = grub_crypto_lookup_md_by_name (hashspec);
  293. + if (!hash)
  294. + {
  295. + grub_crypto_cipher_close (cipher);
  296. + grub_crypto_cipher_close (essiv_cipher);
  297. + grub_crypto_cipher_close (secondary_cipher);
  298. + grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash",
  299. + hashspec);
  300. + return NULL;
  301. + }
  302. +
  303. + newdev = grub_zalloc (sizeof (struct grub_cryptodisk));
  304. + if (!newdev)
  305. + {
  306. + grub_crypto_cipher_close (cipher);
  307. + grub_crypto_cipher_close (essiv_cipher);
  308. + grub_crypto_cipher_close (secondary_cipher);
  309. + return NULL;
  310. + }
  311. + newdev->cipher = cipher;
  312. + newdev->offset = 0;
  313. + newdev->source_disk = NULL;
  314. + newdev->benbi_log = benbi_log;
  315. + newdev->mode = mode;
  316. + newdev->mode_iv = mode_iv;
  317. + newdev->secondary_cipher = secondary_cipher;
  318. + newdev->essiv_cipher = essiv_cipher;
  319. + newdev->essiv_hash = essiv_hash;
  320. + newdev->hash = hash;
  321. + newdev->log_sector_size = 9;
  322. + newdev->total_length = grub_disk_get_size (disk) - newdev->offset;
  323. + grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid));
  324. + COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (uuid));
  325. +
  326. + return newdev;
  327. +}
  328. +
  329. static grub_extcmd_t cmd;
  330. GRUB_MOD_INIT (cryptodisk)
  331. {
  332. grub_disk_dev_register (&grub_cryptodisk_dev);
  333. cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0,
  334. - N_("SOURCE|-u UUID|-a|-b|-H file"),
  335. + N_("SOURCE|-u UUID|-a|-b|-H file|-p -c cipher -d digest"),
  336. N_("Mount a crypto device."), options);
  337. grub_procfs_register ("luks_script", &luks_script);
  338. }
  339. diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c
  340. index 11e437e..4ebe21b 100644
  341. --- a/grub-core/disk/luks.c
  342. +++ b/grub-core/disk/luks.c
  343. @@ -30,8 +30,6 @@
  344. GRUB_MOD_LICENSE ("GPLv3+");
  345. -#define MAX_PASSPHRASE 256
  346. -
  347. #define LUKS_KEY_ENABLED 0x00AC71F3
  348. /* On disk LUKS header */
  349. @@ -76,15 +74,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
  350. char uuid[sizeof (header.uuid) + 1];
  351. char ciphername[sizeof (header.cipherName) + 1];
  352. char ciphermode[sizeof (header.cipherMode) + 1];
  353. - char *cipheriv = NULL;
  354. char hashspec[sizeof (header.hashSpec) + 1];
  355. - grub_crypto_cipher_handle_t cipher = NULL, secondary_cipher = NULL;
  356. - grub_crypto_cipher_handle_t essiv_cipher = NULL;
  357. - const gcry_md_spec_t *hash = NULL, *essiv_hash = NULL;
  358. - const struct gcry_cipher_spec *ciph;
  359. - grub_cryptodisk_mode_t mode;
  360. - grub_cryptodisk_mode_iv_t mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64;
  361. - int benbi_log = 0;
  362. grub_err_t err;
  363. err = GRUB_ERR_NONE;
  364. @@ -119,7 +109,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
  365. iptr++)
  366. {
  367. if (*iptr != '-')
  368. - *optr++ = *iptr;
  369. + *optr++ = *iptr;
  370. }
  371. *optr = 0;
  372. @@ -129,6 +119,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
  373. return NULL;
  374. }
  375. +
  376. /* Make sure that strings are null terminated. */
  377. grub_memcpy (ciphername, header.cipherName, sizeof (header.cipherName));
  378. ciphername[sizeof (header.cipherName)] = 0;
  379. @@ -137,184 +128,10 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
  380. grub_memcpy (hashspec, header.hashSpec, sizeof (header.hashSpec));
  381. hashspec[sizeof (header.hashSpec)] = 0;
  382. - ciph = grub_crypto_lookup_cipher_by_name (ciphername);
  383. - if (!ciph)
  384. - {
  385. - grub_error (GRUB_ERR_FILE_NOT_FOUND, "Cipher %s isn't available",
  386. - ciphername);
  387. - return NULL;
  388. - }
  389. -
  390. - /* Configure the cipher used for the bulk data. */
  391. - cipher = grub_crypto_cipher_open (ciph);
  392. - if (!cipher)
  393. - return NULL;
  394. -
  395. - if (grub_be_to_cpu32 (header.keyBytes) > 1024)
  396. - {
  397. - grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid keysize %d",
  398. - grub_be_to_cpu32 (header.keyBytes));
  399. - grub_crypto_cipher_close (cipher);
  400. - return NULL;
  401. - }
  402. -
  403. - /* Configure the cipher mode. */
  404. - if (grub_strcmp (ciphermode, "ecb") == 0)
  405. - {
  406. - mode = GRUB_CRYPTODISK_MODE_ECB;
  407. - mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
  408. - cipheriv = NULL;
  409. - }
  410. - else if (grub_strcmp (ciphermode, "plain") == 0)
  411. - {
  412. - mode = GRUB_CRYPTODISK_MODE_CBC;
  413. - mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
  414. - cipheriv = NULL;
  415. - }
  416. - else if (grub_memcmp (ciphermode, "cbc-", sizeof ("cbc-") - 1) == 0)
  417. - {
  418. - mode = GRUB_CRYPTODISK_MODE_CBC;
  419. - cipheriv = ciphermode + sizeof ("cbc-") - 1;
  420. - }
  421. - else if (grub_memcmp (ciphermode, "pcbc-", sizeof ("pcbc-") - 1) == 0)
  422. - {
  423. - mode = GRUB_CRYPTODISK_MODE_PCBC;
  424. - cipheriv = ciphermode + sizeof ("pcbc-") - 1;
  425. - }
  426. - else if (grub_memcmp (ciphermode, "xts-", sizeof ("xts-") - 1) == 0)
  427. - {
  428. - mode = GRUB_CRYPTODISK_MODE_XTS;
  429. - cipheriv = ciphermode + sizeof ("xts-") - 1;
  430. - secondary_cipher = grub_crypto_cipher_open (ciph);
  431. - if (!secondary_cipher)
  432. - {
  433. - grub_crypto_cipher_close (cipher);
  434. - return NULL;
  435. - }
  436. - if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
  437. - {
  438. - grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d",
  439. - cipher->cipher->blocksize);
  440. - grub_crypto_cipher_close (cipher);
  441. - grub_crypto_cipher_close (secondary_cipher);
  442. - return NULL;
  443. - }
  444. - if (secondary_cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
  445. - {
  446. - grub_crypto_cipher_close (cipher);
  447. - grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported XTS block size: %d",
  448. - secondary_cipher->cipher->blocksize);
  449. - grub_crypto_cipher_close (secondary_cipher);
  450. - return NULL;
  451. - }
  452. - }
  453. - else if (grub_memcmp (ciphermode, "lrw-", sizeof ("lrw-") - 1) == 0)
  454. - {
  455. - mode = GRUB_CRYPTODISK_MODE_LRW;
  456. - cipheriv = ciphermode + sizeof ("lrw-") - 1;
  457. - if (cipher->cipher->blocksize != GRUB_CRYPTODISK_GF_BYTES)
  458. - {
  459. - grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported LRW block size: %d",
  460. - cipher->cipher->blocksize);
  461. - grub_crypto_cipher_close (cipher);
  462. - return NULL;
  463. - }
  464. - }
  465. - else
  466. - {
  467. - grub_crypto_cipher_close (cipher);
  468. - grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown cipher mode: %s",
  469. - ciphermode);
  470. - return NULL;
  471. - }
  472. -
  473. - if (cipheriv == NULL);
  474. - else if (grub_memcmp (cipheriv, "plain", sizeof ("plain") - 1) == 0)
  475. - mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN;
  476. - else if (grub_memcmp (cipheriv, "plain64", sizeof ("plain64") - 1) == 0)
  477. - mode_iv = GRUB_CRYPTODISK_MODE_IV_PLAIN64;
  478. - else if (grub_memcmp (cipheriv, "benbi", sizeof ("benbi") - 1) == 0)
  479. - {
  480. - if (cipher->cipher->blocksize & (cipher->cipher->blocksize - 1)
  481. - || cipher->cipher->blocksize == 0)
  482. - grub_error (GRUB_ERR_BAD_ARGUMENT, "Unsupported benbi blocksize: %d",
  483. - cipher->cipher->blocksize);
  484. - /* FIXME should we return an error here? */
  485. - for (benbi_log = 0;
  486. - (cipher->cipher->blocksize << benbi_log) < GRUB_DISK_SECTOR_SIZE;
  487. - benbi_log++);
  488. - mode_iv = GRUB_CRYPTODISK_MODE_IV_BENBI;
  489. - }
  490. - else if (grub_memcmp (cipheriv, "null", sizeof ("null") - 1) == 0)
  491. - mode_iv = GRUB_CRYPTODISK_MODE_IV_NULL;
  492. - else if (grub_memcmp (cipheriv, "essiv:", sizeof ("essiv:") - 1) == 0)
  493. - {
  494. - char *hash_str = cipheriv + 6;
  495. -
  496. - mode_iv = GRUB_CRYPTODISK_MODE_IV_ESSIV;
  497. -
  498. - /* Configure the hash and cipher used for ESSIV. */
  499. - essiv_hash = grub_crypto_lookup_md_by_name (hash_str);
  500. - if (!essiv_hash)
  501. - {
  502. - grub_crypto_cipher_close (cipher);
  503. - grub_crypto_cipher_close (secondary_cipher);
  504. - grub_error (GRUB_ERR_FILE_NOT_FOUND,
  505. - "Couldn't load %s hash", hash_str);
  506. - return NULL;
  507. - }
  508. - essiv_cipher = grub_crypto_cipher_open (ciph);
  509. - if (!essiv_cipher)
  510. - {
  511. - grub_crypto_cipher_close (cipher);
  512. - grub_crypto_cipher_close (secondary_cipher);
  513. - return NULL;
  514. - }
  515. - }
  516. - else
  517. - {
  518. - grub_crypto_cipher_close (cipher);
  519. - grub_crypto_cipher_close (secondary_cipher);
  520. - grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown IV mode: %s",
  521. - cipheriv);
  522. - return NULL;
  523. - }
  524. -
  525. - /* Configure the hash used for the AF splitter and HMAC. */
  526. - hash = grub_crypto_lookup_md_by_name (hashspec);
  527. - if (!hash)
  528. - {
  529. - grub_crypto_cipher_close (cipher);
  530. - grub_crypto_cipher_close (essiv_cipher);
  531. - grub_crypto_cipher_close (secondary_cipher);
  532. - grub_error (GRUB_ERR_FILE_NOT_FOUND, "Couldn't load %s hash",
  533. - hashspec);
  534. - return NULL;
  535. - }
  536. + newdev = grub_cryptodisk_create (disk, uuid, ciphername, ciphermode, hashspec);
  537. - newdev = grub_zalloc (sizeof (struct grub_cryptodisk));
  538. - if (!newdev)
  539. - {
  540. - grub_crypto_cipher_close (cipher);
  541. - grub_crypto_cipher_close (essiv_cipher);
  542. - grub_crypto_cipher_close (secondary_cipher);
  543. - return NULL;
  544. - }
  545. - newdev->cipher = cipher;
  546. newdev->offset = grub_be_to_cpu32 (header.payloadOffset);
  547. - newdev->source_disk = NULL;
  548. - newdev->benbi_log = benbi_log;
  549. - newdev->mode = mode;
  550. - newdev->mode_iv = mode_iv;
  551. - newdev->secondary_cipher = secondary_cipher;
  552. - newdev->essiv_cipher = essiv_cipher;
  553. - newdev->essiv_hash = essiv_hash;
  554. - newdev->hash = hash;
  555. - newdev->log_sector_size = 9;
  556. - newdev->total_length = grub_disk_get_size (disk) - newdev->offset;
  557. - grub_memcpy (newdev->uuid, uuid, sizeof (newdev->uuid));
  558. newdev->modname = "luks";
  559. - COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (uuid));
  560. return newdev;
  561. }
  562. @@ -329,7 +146,7 @@ luks_recover_key (grub_disk_t source,
  563. struct grub_luks_phdr header;
  564. grub_size_t keysize;
  565. grub_uint8_t *split_key = NULL;
  566. - char interactive_passphrase[MAX_PASSPHRASE] = "";
  567. + char interactive_passphrase[GRUB_CRYPTODISK_MAX_PASSPHRASE] = "";
  568. grub_uint8_t *passphrase;
  569. grub_size_t passphrase_length;
  570. grub_uint8_t candidate_digest[sizeof (header.mkDigest)];
  571. @@ -376,7 +193,7 @@ luks_recover_key (grub_disk_t source,
  572. /* Use bytestring from key file as passphrase */
  573. passphrase = keyfile_bytes;
  574. passphrase_length = keyfile_bytes_size;
  575. - keyfile_bytes = NULL; /* use it only once */
  576. + keyfile_bytes = NULL; /* use it only once */
  577. }
  578. else
  579. {
  580. @@ -387,7 +204,7 @@ luks_recover_key (grub_disk_t source,
  581. grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
  582. source->partition ? "," : "", tmp ? : "", dev->uuid);
  583. grub_free (tmp);
  584. - if (!grub_password_get (interactive_passphrase, MAX_PASSPHRASE))
  585. + if (!grub_password_get (interactive_passphrase, GRUB_CRYPTODISK_MAX_PASSPHRASE))
  586. {
  587. grub_free (split_key);
  588. return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied");
  589. diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h
  590. index 0299625..4076412 100644
  591. --- a/include/grub/cryptodisk.h
  592. +++ b/include/grub/cryptodisk.h
  593. @@ -54,9 +54,14 @@ typedef enum
  594. #define GRUB_CRYPTODISK_GF_LOG_BYTES (GRUB_CRYPTODISK_GF_LOG_SIZE - 3)
  595. #define GRUB_CRYPTODISK_GF_BYTES (1U << GRUB_CRYPTODISK_GF_LOG_BYTES)
  596. #define GRUB_CRYPTODISK_MAX_KEYLEN 128
  597. +#define GRUB_CRYPTODISK_MAX_PASSPHRASE 256
  598. #define GRUB_CRYPTODISK_MAX_KEYFILE_SIZE 8192
  599. +#define GRUB_CRYPTODISK_PLAIN_CIPHER "aes-cbc-essiv:sha256"
  600. +#define GRUB_CRYPTODISK_PLAIN_DIGEST "ripemd160"
  601. +#define GRUB_CRYPTODISK_PLAIN_KEYSIZE 256
  602. +
  603. struct grub_cryptodisk;
  604. typedef gcry_err_code_t
  605. @@ -159,4 +164,7 @@ grub_util_get_geli_uuid (const char *dev);
  606. grub_cryptodisk_t grub_cryptodisk_get_by_uuid (const char *uuid);
  607. grub_cryptodisk_t grub_cryptodisk_get_by_source_disk (grub_disk_t disk);
  608. +grub_cryptodisk_t grub_cryptodisk_create (grub_disk_t disk, char *uuid,
  609. + char *ciphername, char *ciphermode, char *digest);
  610. +
  611. #endif
  612. --
  613. 2.1.2