2 * LUKS - Linux Unified Key Setup v2, PBKDF2 digest handler (LUKS1 compatible)
4 * Copyright (C) 2015-2023 Red Hat, Inc. All rights reserved.
5 * Copyright (C) 2015-2023 Milan Broz
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "luks2_internal.h"
24 #define LUKS_DIGESTSIZE 20 // since SHA1
25 #define LUKS_SALTSIZE 32
26 #define LUKS_MKD_ITERATIONS_MS 125
28 static int PBKDF2_digest_verify(struct crypt_device *cd,
30 const char *volume_key,
31 size_t volume_key_len)
33 char checkHashBuf[64];
34 json_object *jobj_digest, *jobj1;
36 char *mkDigest = NULL, *mkDigestSalt = NULL;
37 unsigned int mkDigestIterations;
41 /* This can be done only for internally linked digests */
42 jobj_digest = LUKS2_get_digest_jobj(crypt_get_hdr(cd, CRYPT_LUKS2), digest);
46 if (!json_object_object_get_ex(jobj_digest, "hash", &jobj1))
48 hashSpec = json_object_get_string(jobj1);
50 if (!json_object_object_get_ex(jobj_digest, "iterations", &jobj1))
52 mkDigestIterations = json_object_get_int64(jobj1);
54 if (!json_object_object_get_ex(jobj_digest, "salt", &jobj1))
56 r = crypt_base64_decode(&mkDigestSalt, &len, json_object_get_string(jobj1),
57 json_object_get_string_len(jobj1));
60 if (len != LUKS_SALTSIZE)
63 if (!json_object_object_get_ex(jobj_digest, "digest", &jobj1))
65 r = crypt_base64_decode(&mkDigest, &len, json_object_get_string(jobj1),
66 json_object_get_string_len(jobj1));
69 if (len < LUKS_DIGESTSIZE ||
70 len > sizeof(checkHashBuf) ||
71 (len != LUKS_DIGESTSIZE && len != (size_t)crypt_hash_size(hashSpec)))
75 if (crypt_pbkdf(CRYPT_KDF_PBKDF2, hashSpec, volume_key, volume_key_len,
76 mkDigestSalt, LUKS_SALTSIZE,
78 mkDigestIterations, 0, 0) < 0) {
81 if (crypt_backend_memeq(checkHashBuf, mkDigest, len) == 0)
90 static int PBKDF2_digest_store(struct crypt_device *cd,
92 const char *volume_key,
93 size_t volume_key_len)
95 json_object *jobj_digest, *jobj_digests;
96 char salt[LUKS_SALTSIZE], digest_raw[128];
99 struct luks2_hdr *hdr;
100 struct crypt_pbkdf_limits pbkdf_limits;
101 const struct crypt_pbkdf_type *pbkdf_cd;
102 struct crypt_pbkdf_type pbkdf = {
103 .type = CRYPT_KDF_PBKDF2,
104 .time_ms = LUKS_MKD_ITERATIONS_MS,
107 /* Inherit hash from PBKDF setting */
108 pbkdf_cd = crypt_get_pbkdf_type(cd);
110 pbkdf.hash = pbkdf_cd->hash;
112 pbkdf.hash = DEFAULT_LUKS1_HASH;
114 log_dbg(cd, "Setting PBKDF2 type key digest %d.", digest);
116 r = crypt_random_get(cd, salt, LUKS_SALTSIZE, CRYPT_RND_SALT);
120 r = crypt_pbkdf_get_limits(CRYPT_KDF_PBKDF2, &pbkdf_limits);
124 if (crypt_get_pbkdf(cd)->flags & CRYPT_PBKDF_NO_BENCHMARK)
125 pbkdf.iterations = pbkdf_limits.min_iterations;
127 r = crypt_benchmark_pbkdf_internal(cd, &pbkdf, volume_key_len);
132 hmac_size = crypt_hmac_size(pbkdf.hash);
133 if (hmac_size < 0 || hmac_size > (int)sizeof(digest_raw))
136 r = crypt_pbkdf(CRYPT_KDF_PBKDF2, pbkdf.hash, volume_key, volume_key_len,
137 salt, LUKS_SALTSIZE, digest_raw, hmac_size,
138 pbkdf.iterations, 0, 0);
142 jobj_digest = LUKS2_get_digest_jobj(crypt_get_hdr(cd, CRYPT_LUKS2), digest);
145 hdr = crypt_get_hdr(cd, CRYPT_LUKS2);
146 jobj_digest = json_object_new_object();
147 json_object_object_get_ex(hdr->jobj, "digests", &jobj_digests);
150 json_object_object_add(jobj_digest, "type", json_object_new_string("pbkdf2"));
151 json_object_object_add(jobj_digest, "keyslots", json_object_new_array());
152 json_object_object_add(jobj_digest, "segments", json_object_new_array());
153 json_object_object_add(jobj_digest, "hash", json_object_new_string(pbkdf.hash));
154 json_object_object_add(jobj_digest, "iterations", json_object_new_int(pbkdf.iterations));
156 r = crypt_base64_encode(&base64_str, NULL, salt, LUKS_SALTSIZE);
158 json_object_put(jobj_digest);
161 json_object_object_add(jobj_digest, "salt", json_object_new_string(base64_str));
164 r = crypt_base64_encode(&base64_str, NULL, digest_raw, hmac_size);
166 json_object_put(jobj_digest);
169 json_object_object_add(jobj_digest, "digest", json_object_new_string(base64_str));
173 json_object_object_add_by_uint(jobj_digests, digest, jobj_digest);
175 JSON_DBG(cd, jobj_digest, "Digest JSON:");
179 static int PBKDF2_digest_dump(struct crypt_device *cd, int digest)
181 json_object *jobj_digest, *jobj1;
183 /* This can be done only for internally linked digests */
184 jobj_digest = LUKS2_get_digest_jobj(crypt_get_hdr(cd, CRYPT_LUKS2), digest);
188 json_object_object_get_ex(jobj_digest, "hash", &jobj1);
189 log_std(cd, "\tHash: %s\n", json_object_get_string(jobj1));
191 json_object_object_get_ex(jobj_digest, "iterations", &jobj1);
192 log_std(cd, "\tIterations: %" PRIu64 "\n", json_object_get_int64(jobj1));
194 json_object_object_get_ex(jobj_digest, "salt", &jobj1);
195 log_std(cd, "\tSalt: ");
196 hexprint_base64(cd, jobj1, " ", " ");
198 json_object_object_get_ex(jobj_digest, "digest", &jobj1);
199 log_std(cd, "\tDigest: ");
200 hexprint_base64(cd, jobj1, " ", " ");
205 const digest_handler PBKDF2_digest = {
207 .verify = PBKDF2_digest_verify,
208 .store = PBKDF2_digest_store,
209 .dump = PBKDF2_digest_dump,