Skip to content

Commit 27f5411

Browse files
Dmitry Baryshkovsnitm
authored andcommitted
dm crypt: support using encrypted keys
Allow one to use "encrypted" in addition to "user" and "logon" key types for device encryption. Signed-off-by: Dmitry Baryshkov <[email protected]> Signed-off-by: Mike Snitzer <[email protected]>
1 parent 2ef96a5 commit 27f5411

File tree

2 files changed

+58
-19
lines changed

2 files changed

+58
-19
lines changed

drivers/md/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ config DM_UNSTRIPED
269269
config DM_CRYPT
270270
tristate "Crypt target support"
271271
depends on BLK_DEV_DM
272+
depends on (ENCRYPTED_KEYS || ENCRYPTED_KEYS=n)
272273
select CRYPTO
273274
select CRYPTO_CBC
274275
select CRYPTO_ESSIV

drivers/md/dm-crypt.c

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
#include <crypto/aead.h>
3535
#include <crypto/authenc.h>
3636
#include <linux/rtnetlink.h> /* for struct rtattr and RTA macros only */
37+
#include <linux/key-type.h>
3738
#include <keys/user-type.h>
39+
#include <keys/encrypted-type.h>
3840

3941
#include <linux/device-mapper.h>
4042

@@ -2215,12 +2217,47 @@ static bool contains_whitespace(const char *str)
22152217
return false;
22162218
}
22172219

2220+
static int set_key_user(struct crypt_config *cc, struct key *key)
2221+
{
2222+
const struct user_key_payload *ukp;
2223+
2224+
ukp = user_key_payload_locked(key);
2225+
if (!ukp)
2226+
return -EKEYREVOKED;
2227+
2228+
if (cc->key_size != ukp->datalen)
2229+
return -EINVAL;
2230+
2231+
memcpy(cc->key, ukp->data, cc->key_size);
2232+
2233+
return 0;
2234+
}
2235+
2236+
#if defined(CONFIG_ENCRYPTED_KEYS) || defined(CONFIG_ENCRYPTED_KEYS_MODULE)
2237+
static int set_key_encrypted(struct crypt_config *cc, struct key *key)
2238+
{
2239+
const struct encrypted_key_payload *ekp;
2240+
2241+
ekp = key->payload.data[0];
2242+
if (!ekp)
2243+
return -EKEYREVOKED;
2244+
2245+
if (cc->key_size != ekp->decrypted_datalen)
2246+
return -EINVAL;
2247+
2248+
memcpy(cc->key, ekp->decrypted_data, cc->key_size);
2249+
2250+
return 0;
2251+
}
2252+
#endif /* CONFIG_ENCRYPTED_KEYS */
2253+
22182254
static int crypt_set_keyring_key(struct crypt_config *cc, const char *key_string)
22192255
{
22202256
char *new_key_string, *key_desc;
22212257
int ret;
2258+
struct key_type *type;
22222259
struct key *key;
2223-
const struct user_key_payload *ukp;
2260+
int (*set_key)(struct crypt_config *cc, struct key *key);
22242261

22252262
/*
22262263
* Reject key_string with whitespace. dm core currently lacks code for
@@ -2236,40 +2273,41 @@ static int crypt_set_keyring_key(struct crypt_config *cc, const char *key_string
22362273
if (!key_desc || key_desc == key_string || !strlen(key_desc + 1))
22372274
return -EINVAL;
22382275

2239-
if (strncmp(key_string, "logon:", key_desc - key_string + 1) &&
2240-
strncmp(key_string, "user:", key_desc - key_string + 1))
2276+
if (!strncmp(key_string, "logon:", key_desc - key_string + 1)) {
2277+
type = &key_type_logon;
2278+
set_key = set_key_user;
2279+
} else if (!strncmp(key_string, "user:", key_desc - key_string + 1)) {
2280+
type = &key_type_user;
2281+
set_key = set_key_user;
2282+
#if defined(CONFIG_ENCRYPTED_KEYS) || defined(CONFIG_ENCRYPTED_KEYS_MODULE)
2283+
} else if (!strncmp(key_string, "encrypted:", key_desc - key_string + 1)) {
2284+
type = &key_type_encrypted;
2285+
set_key = set_key_encrypted;
2286+
#endif
2287+
} else {
22412288
return -EINVAL;
2289+
}
22422290

22432291
new_key_string = kstrdup(key_string, GFP_KERNEL);
22442292
if (!new_key_string)
22452293
return -ENOMEM;
22462294

2247-
key = request_key(key_string[0] == 'l' ? &key_type_logon : &key_type_user,
2248-
key_desc + 1, NULL);
2295+
key = request_key(type, key_desc + 1, NULL);
22492296
if (IS_ERR(key)) {
22502297
kzfree(new_key_string);
22512298
return PTR_ERR(key);
22522299
}
22532300

22542301
down_read(&key->sem);
22552302

2256-
ukp = user_key_payload_locked(key);
2257-
if (!ukp) {
2258-
up_read(&key->sem);
2259-
key_put(key);
2260-
kzfree(new_key_string);
2261-
return -EKEYREVOKED;
2262-
}
2263-
2264-
if (cc->key_size != ukp->datalen) {
2303+
ret = set_key(cc, key);
2304+
if (ret < 0) {
22652305
up_read(&key->sem);
22662306
key_put(key);
22672307
kzfree(new_key_string);
2268-
return -EINVAL;
2308+
return ret;
22692309
}
22702310

2271-
memcpy(cc->key, ukp->data, cc->key_size);
2272-
22732311
up_read(&key->sem);
22742312
key_put(key);
22752313

@@ -2323,7 +2361,7 @@ static int get_key_size(char **key_string)
23232361
return (*key_string[0] == ':') ? -EINVAL : strlen(*key_string) >> 1;
23242362
}
23252363

2326-
#endif
2364+
#endif /* CONFIG_KEYS */
23272365

23282366
static int crypt_set_key(struct crypt_config *cc, char *key)
23292367
{
@@ -3282,7 +3320,7 @@ static void crypt_io_hints(struct dm_target *ti, struct queue_limits *limits)
32823320

32833321
static struct target_type crypt_target = {
32843322
.name = "crypt",
3285-
.version = {1, 20, 0},
3323+
.version = {1, 21, 0},
32863324
.module = THIS_MODULE,
32873325
.ctr = crypt_ctr,
32883326
.dtr = crypt_dtr,

0 commit comments

Comments
 (0)