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

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