[RFC][PATCH 3/6] encrypted-keys: add key format support

December 23rd, 2010 - 12:40 pm ET by Roberto Sassu | Report spam

This patch introduces a new parameter, called 'format', that defines the
format of data stored by encrypted keys. The 'default' format identifies
encrypted keys containing only the symmetric key, while other formats can
be defined to support additional information. The 'format' parameter is
written in the datablob produced by commands 'keyctl print' or
'keyctl pipe' and is integrity protected by the HMAC.

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>

Documentation/keys-trusted-encrypted.txt | 48 +++++++-
include/keys/encrypted-type.h | 13 +++-
security/keys/encrypted_defined.c | 139 +++++++++++++++++++++--
3 files changed, 141 insertions(+), 59 deletions(-)

diff --git a/Documentation/keys-trusted-encrypted.txt b/Documentation/keys-trusted-encrypted.txt
index 8fb79bc..0afcb50 100644
a/Documentation/keys-trusted-encrypted.txt
+++ b/Documentation/keys-trusted-encrypted.txt
@@ -53,12 +53,19 @@ they are only as secure as the user key encrypting them. The master user key
should therefore be loaded in as secure a way as possible, preferably early in
boot.

+The decrypted portion of encrypted keys can contain either a simple symmetric
+key or a more complex structure. The format of the more complex structure is
+application specific, which is identified by 'format'.
+
Usage:
- keyctl add encrypted name "new key-type:master-key-name keylen" ring
- keyctl add encrypted name "load hex_blob" ring
- keyctl update keyid "update key-type:master-key-name"
+ keyctl add encrypted name "new [format] key-type:master-key-name keylen"
+ ring
+ keyctl add encrypted name "load hex_blob" ring
+ keyctl update keyid "update key-type:master-key-name"
+
+format:= 'default'
+key-type:= 'trusted' | 'user'

-where 'key-type' is either 'trusted' or 'user'.

Examples of trusted and encrypted key usage:

@@ -114,15 +121,25 @@ Reseal a trusted key under new pcr values:
7ef6a24defe4846104209bf0c3eced7fa1a672ed5b125fc9d8cd88b476a658a4434644ef
df8ae9a178e9f83ba9f08d10fa47e4226b98b0702f06b3b8

-Create and save an encrypted key "evm" using the above trusted key "kmk":
+The initial consumer of trusted keys is EVM, which at boot time needs a high
+quality symmetric key for HMAC protection of file metadata. The use of a
+trusted key provides strong guarantees that the EVM key has not been
+compromised by a user level problem, and when sealed to specific boot PCR
+values, protects against boot and offline attacks. Create and save an
+encrypted key "evm" using the above trusted key "kmk":

+option 1: omitting 'format'
$ keyctl add encrypted evm "new trusted:kmk 32" @u
159771175

+option 2: explicitly defining 'format' as 'default'
+ $ keyctl add encrypted evm "new default trusted:kmk 32" @u
+ 159771175
+
$ keyctl print 159771175
- trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382dbbc55
- be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e024717c64
- 5972dcb82ab2dde83376d82b2e3c09ffc
+ default trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b3
+ 82dbbc55be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e0
+ 24717c64 5972dcb82ab2dde83376d82b2e3c09ffc

$ keyctl pipe 159771175 > evm.blob

@@ -132,14 +149,9 @@ Load an encrypted key "evm" from saved blob:
831684262

$ keyctl print 831684262
- trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382dbbc55
- be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e024717c64
- 5972dcb82ab2dde83376d82b2e3c09ffc
-
+ default trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b3
+ 82dbbc55be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e0
+ 24717c64 5972dcb82ab2dde83376d82b2e3c09ffc

-The initial consumer of trusted keys is EVM, which at boot time needs a high
-quality symmetric key for HMAC protection of file metadata. The use of a
-trusted key provides strong guarantees that the EVM key has not been
-compromised by a user level problem, and when sealed to specific boot PCR
-values, protects against boot and offline attacks. Other uses for trusted and
-encrypted keys, such as for disk and file encryption are anticipated.
+Other uses for trusted and encrypted keys, such as for disk and file encryption
+are anticipated.
diff --git a/include/keys/encrypted-type.h b/include/keys/encrypted-type.h
index 9585501..1d45413 100644
a/include/keys/encrypted-type.h
+++ b/include/keys/encrypted-type.h
@@ -1,6 +1,11 @@
/*
* Copyright (C) 2010 IBM Corporation
- * Author: Mimi Zohar <zohar@us.ibm.com>
+ * Copyright (C) 2010 Politecnico di Torino, Italy
+ * TORSEC group -- http://security.polito.it
+ *
+ * Authors:
+ * Mimi Zohar <zohar@us.ibm.com>
+ * Roberto Sassu <roberto.sassu@polito.it>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,13 +20,17 @@

struct encrypted_key_payload {
struct rcu_head rcu;
+ char *format; /* datablob: format */
char *master_desc; /* datablob: master key name */
char *datalen; /* datablob: decrypted key length */
u8 *iv; /* datablob: iv */
u8 *encrypted_data; /* datablob: encrypted data */
unsigned short datablob_len; /* length of datablob */
unsigned short decrypted_datalen; /* decrypted data length */
- u8 decrypted_data[0]; /* decrypted data + datablob + hmac */
+ unsigned short payload_datalen; /* payload data length */
+ unsigned short encrypted_key_format; /* encrypted key format */
+ u8 *decrypted_data; /* decrypted data */
+ u8 payload_data[0]; /* payload data + datablob + hmac */
};

extern struct key_type key_type_encrypted;
diff --git a/security/keys/encrypted_defined.c b/security/keys/encrypted_defined.c
index 2bb2c47..7a914ab 100644
a/security/keys/encrypted_defined.c
+++ b/security/keys/encrypted_defined.c
@@ -1,8 +1,11 @@
/*
* Copyright (C) 2010 IBM Corporation
+ * Copyright (C) 2010 Politecnico di Torino, Italy
+ * TORSEC group -- http://security.polito.it
*
- * Author:
+ * Authors:
* Mimi Zohar <zohar@us.ibm.com>
+ * Roberto Sassu <roberto.sassu@polito.it>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -37,6 +40,7 @@ static const char KEY_USER_PREFIX[] = "user:";
static const char hash_alg[] = "sha256";
static const char hmac_alg[] = "hmac(sha256)";
static const char blkcipher_alg[] = "cbc(aes)";
+static const char key_format_default[] = "default";
static unsigned int ivsize;
static int blksize;

@@ -58,6 +62,15 @@ enum {
Opt_err = -1, Opt_new, Opt_load, Opt_update
};

+enum {
+ Opt_error = -1, Opt_default
+};
+
+static const match_table_t key_format_tokens = {
+ {Opt_default, "default"},
+ {Opt_error, NULL}
+};
+
static const match_table_t key_tokens = {
{Opt_new, "new"},
{Opt_load, "load"},
@@ -118,8 +131,9 @@ out:
* datablob_parse - parse the keyctl data
*
* datablob format:
- * new <master-key name> <decrypted data length>
- * load <master-key name> <decrypted data length> <encrypted iv + data>
+ * new [<format>] <master-key name> <decrypted data length>
+ * load [<format>] <master-key name> <decrypted data length>
+ * <encrypted iv + data>
* update <new-master-key name>
*
* Tokenizes a copy of the keyctl data, returning a pointer to each token,
@@ -127,12 +141,14 @@ out:
*
* On success returns 0, otherwise -EINVAL.
*/
-static int datablob_parse(char *datablob, char **master_desc,
- char **decrypted_datalen, char **hex_encoded_iv)
+static int datablob_parse(char *datablob, const char **format,
+ char **master_desc, char **decrypted_datalen,
+ char **hex_encoded_iv)
{
substring_t args[MAX_OPT_ARGS];
int ret = -EINVAL;
int key_cmd;
+ int key_format;
char *p, *keyword;

keyword = strsep(&datablob, " \t");
@@ -142,7 +158,24 @@ static int datablob_parse(char *datablob, char **master_desc,
}
key_cmd = match_token(keyword, key_tokens, args);

- *master_desc = strsep(&datablob, " \t");
+ /* Get optional format: default */
+ p = strsep(&datablob, " \t");
+ if (!p) {
+ pr_err("encrypted_key: insufficient parameters specified");
+ return ret;
+ }
+
+ key_format = match_token(p, key_format_tokens, args);
+ switch (key_format) {
+ case Opt_default:
+ *format = p;
+ *master_desc = strsep(&datablob, " \t");
+ break;
+ case Opt_error:
+ *master_desc = p;
+ break;
+ }
+
if (!*master_desc) {
pr_err("encrypted_key: master key parameter is missing");
goto out;
@@ -219,8 +252,8 @@ static char *datablob_format(struct encrypted_key_payload *epayload,
ascii_buf[asciiblob_len] = '\0';

/* copy datablob master_desc and datalen strings */
- len = sprintf(ascii_buf, "%s %s ", epayload->master_desc,
- epayload->datalen);
+ len = sprintf(ascii_buf, "%s %s %s ", epayload->format,
+ epayload->master_desc, epayload->datalen);

/* convert the hex encoded iv, encrypted-data and HMAC to ascii */
bufp = &ascii_buf[len];
@@ -461,9 +494,9 @@ static int datablob_hmac_append(struct encrypted_key_payload *epayload,
if (ret < 0)
goto out;

- digest = epayload->master_desc + epayload->datablob_len;
+ digest = epayload->format + epayload->datablob_len;
ret = calc_hmac(digest, derived_key, sizeof derived_key,
- epayload->master_desc, epayload->datablob_len);
+ epayload->format, epayload->datablob_len);
if (!ret)
dump_hmac(NULL, digest, HASH_SIZE);
out:
@@ -472,26 +505,35 @@ out:

/* verify HMAC before decrypting encrypted key */
static int datablob_hmac_verify(struct encrypted_key_payload *epayload,
- const u8 *master_key, size_t master_keylen)
+ const u8 *format, const u8 *master_key,
+ size_t master_keylen)
{
u8 derived_key[HASH_SIZE];
u8 digest[HASH_SIZE];
int ret;
+ char *p;
+ unsigned short len;

ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen);
if (ret < 0)
goto out;

- ret = calc_hmac(digest, derived_key, sizeof derived_key,
- epayload->master_desc, epayload->datablob_len);
+ len = epayload->datablob_len;
+ if (!format) {
+ p = epayload->master_desc;
+ len -= strlen(epayload->format) + 1;
+ } else
+ p = epayload->format;
+
+ ret = calc_hmac(digest, derived_key, sizeof derived_key, p, len);
if (ret < 0)
goto out;
- ret = memcmp(digest, epayload->master_desc + epayload->datablob_len,
+ ret = memcmp(digest, epayload->format + epayload->datablob_len,
sizeof digest);
if (ret) {
ret = -EINVAL;
dump_hmac("datablob",
- epayload->master_desc + epayload->datablob_len,
+ epayload->format + epayload->datablob_len,
HASH_SIZE);
dump_hmac("calc", digest, HASH_SIZE);
}
@@ -536,13 +578,16 @@ out:

/* Allocate memory for decrypted key and datablob. */
static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
+ const char *format,
const char *master_desc,
const char *datalen)
{
struct encrypted_key_payload *epayload = NULL;
unsigned short datablob_len;
unsigned short decrypted_datalen;
+ unsigned short payload_datalen;
unsigned int encrypted_datalen;
+ unsigned int format_len;
long dlen;
int ret;

@@ -550,29 +595,32 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
if (ret < 0 || dlen < MIN_DATA_SIZE || dlen > MAX_DATA_SIZE)
return ERR_PTR(-EINVAL);

+ format_len = (!format) ? strlen(key_format_default) : strlen(format);
decrypted_datalen = dlen;
+ payload_datalen = decrypted_datalen;
encrypted_datalen = roundup(decrypted_datalen, blksize);

- datablob_len = strlen(master_desc) + 1 + strlen(datalen) + 1
- + ivsize + 1 + encrypted_datalen;
+ datablob_len = format_len + 1 + strlen(master_desc) + 1
+ + strlen(datalen) + 1 + ivsize + 1 + encrypted_datalen;

- ret = key_payload_reserve(key, decrypted_datalen + datablob_len
+ ret = key_payload_reserve(key, payload_datalen + datablob_len
+ HASH_SIZE + 1);
if (ret < 0)
return ERR_PTR(ret);

- epayload = kzalloc(sizeof(*epayload) + decrypted_datalen +
+ epayload = kzalloc(sizeof(*epayload) + payload_datalen +
datablob_len + HASH_SIZE + 1, GFP_KERNEL);
if (!epayload)
return ERR_PTR(-ENOMEM);

+ epayload->payload_datalen = payload_datalen;
epayload->decrypted_datalen = decrypted_datalen;
epayload->datablob_len = datablob_len;
return epayload;
}

static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
- const char *hex_encoded_iv)
+ const char *format, const char *hex_encoded_iv)
{
struct key *mkey;
u8 derived_key[HASH_SIZE];
@@ -593,14 +641,14 @@ static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
hex2bin(epayload->iv, hex_encoded_iv, ivsize);
hex2bin(epayload->encrypted_data, hex_encoded_data, encrypted_datalen);

- hmac = epayload->master_desc + epayload->datablob_len;
+ hmac = epayload->format + epayload->datablob_len;
hex2bin(hmac, hex_encoded_data + (encrypted_datalen * 2), HASH_SIZE);

mkey = request_master_key(epayload, &master_key, &master_keylen);
if (IS_ERR(mkey))
return PTR_ERR(mkey);

- ret = datablob_hmac_verify(epayload, master_key, master_keylen);
+ ret = datablob_hmac_verify(epayload, format, master_key, master_keylen);
if (ret < 0) {
pr_err("encrypted_key: bad hmac (%d)", ret);
goto out;
@@ -620,14 +668,23 @@ out:
}

static void __ekey_init(struct encrypted_key_payload *epayload,
- const char *master_desc, const char *datalen)
+ const char *format, const char *master_desc,
+ const char *datalen)
{
- epayload->master_desc = epayload->decrypted_data
- + epayload->decrypted_datalen;
+ unsigned int format_len;
+
+ format_len = (!format) ? strlen(key_format_default) : strlen(format);
+ epayload->format = epayload->payload_data + epayload->payload_datalen;
+ epayload->master_desc = epayload->format + format_len + 1;
epayload->datalen = epayload->master_desc + strlen(master_desc) + 1;
epayload->iv = epayload->datalen + strlen(datalen) + 1;
epayload->encrypted_data = epayload->iv + ivsize + 1;
+ epayload->decrypted_data = epayload->payload_data;

+ if (!format)
+ memcpy(epayload->format, key_format_default, format_len);
+ else
+ memcpy(epayload->format, format, format_len);
memcpy(epayload->master_desc, master_desc, strlen(master_desc));
memcpy(epayload->datalen, datalen, strlen(datalen));
}
@@ -639,19 +696,19 @@ static void __ekey_init(struct encrypted_key_payload *epayload,
* itself. For an old key, decrypt the hex encoded data.
*/
static int encrypted_init(struct encrypted_key_payload *epayload,
- const char *master_desc, const char *datalen,
- const char *hex_encoded_iv)
+ const char *format, const char *master_desc,
+ const char *datalen, const char *hex_encoded_iv)
{
int ret = 0;

- __ekey_init(epayload, master_desc, datalen);
+ __ekey_init(epayload, format, master_desc, datalen);
if (!hex_encoded_iv) {
get_random_bytes(epayload->iv, ivsize);

get_random_bytes(epayload->decrypted_data,
epayload->decrypted_datalen);
} else
- ret = encrypted_key_decrypt(epayload, hex_encoded_iv);
+ ret = encrypted_key_decrypt(epayload, format, hex_encoded_iv);
return ret;
}

@@ -668,6 +725,7 @@ static int encrypted_instantiate(struct key *key, const void *data,
{
struct encrypted_key_payload *epayload = NULL;
char *datablob = NULL;
+ const char *format = NULL;
char *master_desc = NULL;
char *decrypted_datalen = NULL;
char *hex_encoded_iv = NULL;
@@ -681,17 +739,18 @@ static int encrypted_instantiate(struct key *key, const void *data,
return -ENOMEM;
datablob[datalen] = 0;
memcpy(datablob, data, datalen);
- ret = datablob_parse(datablob, &master_desc, &decrypted_datalen,
- &hex_encoded_iv);
+ ret = datablob_parse(datablob, &format, &master_desc,
+ &decrypted_datalen, &hex_encoded_iv);
if (ret < 0)
goto out;

- epayload = encrypted_key_alloc(key, master_desc, decrypted_datalen);
+ epayload = encrypted_key_alloc(key, format, master_desc,
+ decrypted_datalen);
if (IS_ERR(epayload)) {
ret = PTR_ERR(epayload);
goto out;
}
- ret = encrypted_init(epayload, master_desc, decrypted_datalen,
+ ret = encrypted_init(epayload, format, master_desc, decrypted_datalen,
hex_encoded_iv);
if (ret < 0) {
kfree(epayload);
@@ -728,6 +787,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
struct encrypted_key_payload *new_epayload;
char *buf;
char *new_master_desc = NULL;
+ const char *format = NULL;
int ret = 0;

if (datalen <= 0 || datalen > 32767 || !data)
@@ -739,7 +799,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)

buf[datalen] = 0;
memcpy(buf, data, datalen);
- ret = datablob_parse(buf, &new_master_desc, NULL, NULL);
+ ret = datablob_parse(buf, &format, &new_master_desc, NULL, NULL);
if (ret < 0)
goto out;

@@ -747,18 +807,19 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
if (ret < 0)
goto out;

- new_epayload = encrypted_key_alloc(key, new_master_desc,
- epayload->datalen);
+ new_epayload = encrypted_key_alloc(key, epayload->format,
+ new_master_desc, epayload->datalen);
if (IS_ERR(new_epayload)) {
ret = PTR_ERR(new_epayload);
goto out;
}

- __ekey_init(new_epayload, new_master_desc, epayload->datalen);
+ __ekey_init(new_epayload, epayload->format, new_master_desc,
+ epayload->datalen);

memcpy(new_epayload->iv, epayload->iv, ivsize);
- memcpy(new_epayload->decrypted_data, epayload->decrypted_data,
- epayload->decrypted_datalen);
+ memcpy(new_epayload->payload_data, epayload->payload_data,
+ epayload->payload_datalen);

rcu_assign_pointer(key->payload.data, new_epayload);
call_rcu(&epayload->rcu, encrypted_rcu_free);
1.7.2.3



MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIO1zCCBHgw
ggNgoAMCAQICAQIwDQYJKoZIhvcNAQEFBQAwQzEQMA4GA1UEChMHRXVyb1BLSTEVMBMGA1UECxMM
RXVyb1BLSSByb290MRgwFgYDVQQDEw9FdXJvUEtJIHJvb3QgQ0EwHhcNMTAxMjE4MTM0NjQ3WhcN
MjAxMjMxMjM1OTU5WjBUMQswCQYDVQQGEwJJVDEQMA4GA1UEChMHRXVyb1BLSTEWMBQGA1UECxMN
RXVyb1BLSSBJdGFseTEbMBkGA1UEAxMSRXVyb1BLSSBJdGFsaWFuIENBMIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEAl8TJXW2u1qPxn0/lyIBNvH1S5LBM3SkLFoNHPSx8TZiZ+f7nKXen
N2h07KhIQRmycQn3FQqVUzm8fuV6zK8Je20Jvp/isL/fPcPQbu5G1+iaH7uU/9Fuq7MAFL+Pd+Su
JGSEV0Rm7jENI3649qnZLZvXyw4To2kqQBlCUJLxSfyi74rIqqEDX5eimCf+CK8mU9gtzOZZCCh0
yhFU3IHR2giypasinSDss5PO+LbVLh4V6NMU5oZx2tx5FKaeYJIhURqFLxRVMlf2EGbe4LOuAlav
1GZt8udZoiH/b+D9j7hbd6nNHumjS8nC3hl7YybxFgwMnpRPc3QDKMGj4yf6IQIDAQABo4IBZDCC
AWAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNB15T/ryrprllF8
IKWYvfNn07RKMB8GA1UdIwQYMBaAFPBxHCgzWLfFxrXDv1F1qFD0nNI0MEkGA1UdIARCMEAwPgYK
KwYBBAGpBwEBAjAwMC4GCCsGAQUFBwIBFiJodHRwOi8vd3d3LmV1cm9wa2kub3JnL2NhL2Nwcy8x
LjIvMHEGCCsGAQUFBwEBBGUwYzAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZXVyb3BraS5vcmcw
PAYIKwYBBQUHMAKGMGh0dHA6Ly93d3cuZXVyb3BraS5vcmcvY2EvY2VydHMvZXVyb3BraV9yb290
LmNlcjA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vd3d3LmV1cm9wa2kub3JnL2NhL2NybC9ldXJv
cGtpX3Jvb3QuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCEMt4zH90/bCHAZvshNrqwjolRBncf0NAC
l1MZ/PqIsg6Jl56hS39cT2RiBwWnbcgLX7BDOx9jrBFYpK0XiWxyoNKU2fDjLJpViSiBjcGTykTt
DE1ciWCwWTggydsMJqYKif+nEwY9Xyu4HBXEWOng9y2Vu5u5tsHXQKLECBvNwMU28sRhQIkJXxX+
IIAiz/DcxiTU2wDP9N+gIxcGt+fuKTr0iYp1U6t3HC3Iezu87H0DfHEJ3lcIBznbiYwLkJ6eP4pB
uH51zNdEhACQQVsERWtzzK1C/41FPgVuqFLQUvUTbOQ9M20Z0rjLKtZ38rw9rWzeHYa1qZSIPwx2
PQwzMIIE8zCCA9ugAwIBAgIBATANBgkqhkiG9w0BAQUFADBUMQswCQYDVQQGEwJJVDEQMA4GA1UE
ChMHRXVyb1BLSTEWMBQGA1UECxMNRXVyb1BLSSBJdGFseTEbMBkGA1UEAxMSRXVyb1BLSSBJdGFs
aWFuIENBMB4XDTEwMTIxODEzNTgyMloXDTIwMTIzMTIzNTk1OVowZTELMAkGA1UEBhMCSVQxHjAc
BgNVBAoTFVBvbGl0ZWNuaWNvIGRpIFRvcmlubzE2MDQGA1UEAxMtUG9saXRlY25pY28gZGkgVG9y
aW5vIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEAyGmPlfxVASfEwSPFkDAcANZzFdz9O58KpCEHKkswnH5qjC/1B+v3qOtfCkP84qXpzPcGa/Sz
/ig/n6h17ZtYVexUQpZHcny8K6wXU2+08jXqDy3me6Zn4kZmoLdmm9RM2w4NTFv4zkvhPbM207ga
pmWAOEH1A4qr7vUt4qn5Herlwhe1IE9ZiIfoQ9vNAlB3FxuHd3136vGa1bVbguYaqMEvZgZN7Oxt
qBuweZIxfgOPDtPK4VH2qQE2EsuIeLPPQB02pb3ldj7/kbNNlqTuTkUbHDDNH+w3pD9KPXEdxY3D
5E6jVpS1/mTmNVBpJwcOOLEZuotAV//Z8i0d8JEwxwIDAQABo4IBvTCCAbkwDwYDVR0TAQH/BAUw
AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFM2bW1ue6nYhxBBo6NItN9sfL8jkMB8GA1Ud
IwQYMBaAFNB15T/ryrprllF8IKWYvfNn07RKMIGRBgNVHSAEgYkwgYYwPgYKKwYBBAGpBwEBAjAw
MC4GCCsGAQUFBwIBFiJodHRwOi8vd3d3LmV1cm9wa2kub3JnL2NhL2Nwcy8xLjIvMEQGCisGAQQB
qQcCAQIwNjA0BggrBgEFBQcCARYoaHR0cDovL3d3dy5pdGFseS5ldXJvcGtpLm9yZy9jYS9jcHMv
MS4yLzB+BggrBgEFBQcBAQRyMHAwKQYIKwYBBQUHMAGGHWh0dHA6Ly9vY3NwLml0YWx5LmV1cm9w
a2kub3JnMEMGCCsGAQUFBzAChjdodHRwOi8vd3d3Lml0YWx5LmV1cm9wa2kub3JnL2NhL2NlcnRz
L2V1cm9wa2lfaXRhbHkuY2VyMEIGA1UdHwQ7MDkwN6A1oDOGMWh0dHA6Ly93d3cuaXRhbHkuZXVy
b3BraS5vcmcvY2EvY3JsL2l0YWx5X2NybC5jcmwwDQYJKoZIhvcNAQEFBQADggEBAFNUlYhQGVuP
EVBOSNEuC80+3TebY0iGAK35IggW4LiuEHXRWoeKwBbryFfEcR8VnTovF4wufegac+uJZB2k+QLs
wC3zuJLIgbo593W83ShSG5aCJioMoQ5X9Zfd+j1BfIV/zARyhorEvgC7doGfBVxG3qAmQEYbonot
hz4UJWld3Gd3zmwpqpNMLG2JO3BJWOrAun9SWPVRLOE/92Pq/jTMB6Lkse0KNJTBbNHPUzydOzPU
tPA7JvMDnzb6L98hVVqKoxmJw3C2sV/NOl/tuTfS6dnZypZstRaOV0JSWgP4PAqcPte0N40h8q4D
/Rdg5P7EcUklgZqL57cyUCCQro8wggVgMIIESKADAgECAgICuzANBgkqhkiG9w0BAQUFADBlMQsw
CQYDVQQGEwJJVDEeMBwGA1UEChMVUG9saXRlY25pY28gZGkgVG9yaW5vMTYwNAYDVQQDEy1Qb2xp
dGVjbmljbyBkaSBUb3Jpbm8gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAxMjIwMTExOTU0
WhcNMTUxMjMxMjM1OTU5WjBfMQswCQYDVQQGEwJJVDEeMBwGA1UEChMVUG9saXRlY25pY28gZGkg
VG9yaW5vMRcwFQYDVQQDEw5Sb2JlcnRvICBTYXNzdTEXMBUGCgmSJomT8ixkAQETB2QwMjEzMDUw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDS6p4SaJdmmJHJu9On9ZohhBFE2GgYiY7Y
tRnhhQJANfOtHEhSbpUMaSOfq/Pna6ipR5nAFrlM8cOGcSHZdxrPcgzeJU7F2v1fl2ThvFOcTIkc
C1aAJGQUuCaCXDlQt+KFecJWTrRZnalMHZueO+J6cgHcvR1CQz5e88dSzo3QXZy0w/hxGL9Ht9ve
lqsl48ohBk2rs/svAOCp6GfqT1Yxwx1p87d3ViTrmuZB4/X+da39nJqmo6AZ/y3Zg+r91BgNcfsH
VqFT0JTcG6qRIaeqTtqVYpYl+rH1rZzYCakDyQyys66sBvaXyaiMr0M+SpyH+LaGz5bDn5Odq16F
YEq7AgMBAAGjggIeMIICGjAOBgNVHQ8BAf8EBAMCA/gwJwYDVR0lBCAwHgYIKwYBBQUHAwIGCCsG
AQUFBwMDBggrBgEFBQcDBDAiBgNVHREEGzAZgRdyb2JlcnRvLnNhc3N1QHBvbGl0by5pdDAMBgNV
HRMBAf8EAjAAMB0GA1UdDgQWBBQgKbXSXn+j769x0tsZQ9pSOzIIdDAfBgNVHSMEGDAWgBTNm1tb
nup2IcQQaOjSLTfbHy/I5DCBywYDVR0gBIHDMIHAMD4GCisGAQQBqQcBAQIwMDAuBggrBgEFBQcC
ARYiaHR0cDovL3d3dy5ldXJvcGtpLm9yZy9jYS9jcHMvMS4yLzBEBgorBgEEAakHAgECMDYwNAYI
KwYBBQUHAgEWKGh0dHA6Ly93d3cuaXRhbHkuZXVyb3BraS5vcmcvY2EvY3BzLzEuMi8wOAYKKwYB
BAGVYgECAjAqMCgGCCsGAQUFBwIBFhxodHRwOi8vY2EucG9saXRvLml0L2Nwcy8yLjIvMGYGCCsG
AQUFBwEBBFowWDAhBggrBgEFBQcwAYYVaHR0cDovL29jc3AucG9saXRvLml0MDMGCCsGAQUFBzAC
hidodHRwOi8vY2EucG9saXRvLml0L2NlcnRzL3BvbGl0b19jYS5jZXIwNwYDVR0fBDAwLjAsoCqg
KIYmaHR0cDovL2NhLnBvbGl0by5pdC9jcmwvcG9saXRvX2NybC5jcmwwDQYJKoZIhvcNAQEFBQAD
ggEBADMe0aHcBJXV6pMJPVVSt1Vazd8YLuTLO45Igs9Sb2LuaO6pvcDGvq9dEJnBhP1B+zBAK6WE
A1PWb66xC4QXaJnlGZTXS3XeBivHWm6BNOH2kNeU0HBeGZCV/n5r70TPxkEAcc7u8YY2i6CiMM42
8YhZK8ZjoN9D3QNIRf4HZgh0FTbf8eL/XvBbK/oPC+Rew+Qql6M3DHnaS1q2SKUwwO/4VXA4JsOd
atFI68AMXH0Xx9UIcjRi+kvsyvwHlc0Z8AoAtfRMoIl4zFF4Qaowec2UunBKYlqPpFTtU9czuoEP
12A86nqSVsoNok2mZOeYa9IdIjeE2rfdKx6k3YNRg08xggIcMIICGAIBATBrMGUxCzAJBgNVBAYT
AklUMR4wHAYDVQQKExVQb2xpdGVjbmljbyBkaSBUb3Jpbm8xNjA0BgNVBAMTLVBvbGl0ZWNuaWNv
IGRpIFRvcmlubyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQICArswCQYFKw4DAhoFAKCBhzAYBgkq
hkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xMDEyMjMxNzM1MDBaMCMGCSqG
SIb3DQEJBDEWBBSDSgEdNhf9K1fX32wSfilrP/URWjAoBgkqhkiG9w0BCQ8xGzAZMAsGCWCGSAFl
AwQBAjAKBggqhkiG9w0DBzANBgkqhkiG9w0BAQEFAASCAQCoDgwKSSyqEaT4BjEtkdmLaEWKgyKN
veCo5XOJmGwLbgAPMy7g5SWkamH+IuX42BRhjG4CQ1K5BKQ/kL5Oq0tmI1lMNuRXE1DqW80YcN7P
4MVx9INDlAP6+q0qd2E5S8KV27xLiNVDEXchluj6sNYRw8QqxnaeXE7ihsU2/kFQBDiHz03izbaF
0/ms+mSQR99bwCJ2jl3sZyXfKWtKQxy9mQuy9ipgSKeEBcBV3bip8R3P6g3y0Y268/0Afl+FS1kj
svCQboElzrWYQKuZRz4VuegedSBDBL+gqKh9Tc4V+lIO7m5B02YwdqhCfG+eOBx2YDiZ/xPLSug7
X9jq/BOsAAAAAAAA

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
email Follow the discussionReplies 1 replyReplies Make a reply

Replies

#1 Mimi Zohar
December 24th, 2010 - 10:50 am ET | Report spam
On Thu, 2010-12-23 at 18:35 +0100, Roberto Sassu wrote:
This patch introduces a new parameter, called 'format', that defines the
format of data stored by encrypted keys. The 'default' format identifies
encrypted keys containing only the symmetric key, while other formats can
be defined to support additional information. The 'format' parameter is
written in the datablob produced by commands 'keyctl print' or
'keyctl pipe' and is integrity protected by the HMAC.

Signed-off-by: Roberto Sassu



Nice!

Acked-by: Mimi Zohar


Documentation/keys-trusted-encrypted.txt | 48 +++++++-
include/keys/encrypted-type.h | 13 +++-
security/keys/encrypted_defined.c | 139 +++++++++++++++++++++--
3 files changed, 141 insertions(+), 59 deletions(-)

diff --git a/Documentation/keys-trusted-encrypted.txt b/Documentation/keys-trusted-encrypted.txt
index 8fb79bc..0afcb50 100644
a/Documentation/keys-trusted-encrypted.txt
+++ b/Documentation/keys-trusted-encrypted.txt
@@ -53,12 +53,19 @@ they are only as secure as the user key encrypting them. The master user key
should therefore be loaded in as secure a way as possible, preferably early in
boot.

+The decrypted portion of encrypted keys can contain either a simple symmetric
+key or a more complex structure. The format of the more complex structure is
+application specific, which is identified by 'format'.
+
Usage:
- keyctl add encrypted name "new key-type:master-key-name keylen" ring
- keyctl add encrypted name "load hex_blob" ring
- keyctl update keyid "update key-type:master-key-name"
+ keyctl add encrypted name "new [format] key-type:master-key-name keylen"
+ ring
+ keyctl add encrypted name "load hex_blob" ring
+ keyctl update keyid "update key-type:master-key-name"
+
+format:= 'default'
+key-type:= 'trusted' | 'user'

-where 'key-type' is either 'trusted' or 'user'.

Examples of trusted and encrypted key usage:

@@ -114,15 +121,25 @@ Reseal a trusted key under new pcr values:
7ef6a24defe4846104209bf0c3eced7fa1a672ed5b125fc9d8cd88b476a658a4434644ef
df8ae9a178e9f83ba9f08d10fa47e4226b98b0702f06b3b8

-Create and save an encrypted key "evm" using the above trusted key "kmk":
+The initial consumer of trusted keys is EVM, which at boot time needs a high
+quality symmetric key for HMAC protection of file metadata. The use of a
+trusted key provides strong guarantees that the EVM key has not been
+compromised by a user level problem, and when sealed to specific boot PCR
+values, protects against boot and offline attacks. Create and save an
+encrypted key "evm" using the above trusted key "kmk":

+option 1: omitting 'format'
$ keyctl add encrypted evm "new trusted:kmk 32" @u
159771175

+option 2: explicitly defining 'format' as 'default'
+ $ keyctl add encrypted evm "new default trusted:kmk 32" @u
+ 159771175
+
$ keyctl print 159771175
- trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382dbbc55
- be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e024717c64
- 5972dcb82ab2dde83376d82b2e3c09ffc
+ default trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b3
+ 82dbbc55be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e0
+ 24717c64 5972dcb82ab2dde83376d82b2e3c09ffc

$ keyctl pipe 159771175 > evm.blob

@@ -132,14 +149,9 @@ Load an encrypted key "evm" from saved blob:
831684262

$ keyctl print 831684262
- trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382dbbc55
- be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e024717c64
- 5972dcb82ab2dde83376d82b2e3c09ffc
-
+ default trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b3
+ 82dbbc55be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e0
+ 24717c64 5972dcb82ab2dde83376d82b2e3c09ffc

-The initial consumer of trusted keys is EVM, which at boot time needs a high
-quality symmetric key for HMAC protection of file metadata. The use of a
-trusted key provides strong guarantees that the EVM key has not been
-compromised by a user level problem, and when sealed to specific boot PCR
-values, protects against boot and offline attacks. Other uses for trusted and
-encrypted keys, such as for disk and file encryption are anticipated.
+Other uses for trusted and encrypted keys, such as for disk and file encryption
+are anticipated.
diff --git a/include/keys/encrypted-type.h b/include/keys/encrypted-type.h
index 9585501..1d45413 100644
a/include/keys/encrypted-type.h
+++ b/include/keys/encrypted-type.h
@@ -1,6 +1,11 @@
/*
* Copyright (C) 2010 IBM Corporation
- * Author: Mimi Zohar
+ * Copyright (C) 2010 Politecnico di Torino, Italy
+ * TORSEC group -- http://security.polito.it
+ *
+ * Authors:
+ * Mimi Zohar
+ * Roberto Sassu
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,13 +20,17 @@

struct encrypted_key_payload {
struct rcu_head rcu;
+ char *format; /* datablob: format */
char *master_desc; /* datablob: master key name */
char *datalen; /* datablob: decrypted key length */
u8 *iv; /* datablob: iv */
u8 *encrypted_data; /* datablob: encrypted data */
unsigned short datablob_len; /* length of datablob */
unsigned short decrypted_datalen; /* decrypted data length */
- u8 decrypted_data[0]; /* decrypted data + datablob + hmac */
+ unsigned short payload_datalen; /* payload data length */
+ unsigned short encrypted_key_format; /* encrypted key format */
+ u8 *decrypted_data; /* decrypted data */
+ u8 payload_data[0]; /* payload data + datablob + hmac */
};

extern struct key_type key_type_encrypted;
diff --git a/security/keys/encrypted_defined.c b/security/keys/encrypted_defined.c
index 2bb2c47..7a914ab 100644
a/security/keys/encrypted_defined.c
+++ b/security/keys/encrypted_defined.c
@@ -1,8 +1,11 @@
/*
* Copyright (C) 2010 IBM Corporation
+ * Copyright (C) 2010 Politecnico di Torino, Italy
+ * TORSEC group -- http://security.polito.it
*
- * Author:
+ * Authors:
* Mimi Zohar
+ * Roberto Sassu
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -37,6 +40,7 @@ static const char KEY_USER_PREFIX[] = "user:";
static const char hash_alg[] = "sha256";
static const char hmac_alg[] = "hmac(sha256)";
static const char blkcipher_alg[] = "cbc(aes)";
+static const char key_format_default[] = "default";
static unsigned int ivsize;
static int blksize;

@@ -58,6 +62,15 @@ enum {
Opt_err = -1, Opt_new, Opt_load, Opt_update
};

+enum {
+ Opt_error = -1, Opt_default
+};
+
+static const match_table_t key_format_tokens = {
+ {Opt_default, "default"},
+ {Opt_error, NULL}
+};
+
static const match_table_t key_tokens = {
{Opt_new, "new"},
{Opt_load, "load"},
@@ -118,8 +131,9 @@ out:
* datablob_parse - parse the keyctl data
*
* datablob format:
- * new <master-key name> <decrypted data length>
- * load <master-key name> <decrypted data length> <encrypted iv + data>
+ * new [<format>] <master-key name> <decrypted data length>
+ * load [<format>] <master-key name> <decrypted data length>
+ * <encrypted iv + data>
* update <new-master-key name>
*
* Tokenizes a copy of the keyctl data, returning a pointer to each token,
@@ -127,12 +141,14 @@ out:
*
* On success returns 0, otherwise -EINVAL.
*/
-static int datablob_parse(char *datablob, char **master_desc,
- char **decrypted_datalen, char **hex_encoded_iv)
+static int datablob_parse(char *datablob, const char **format,
+ char **master_desc, char **decrypted_datalen,
+ char **hex_encoded_iv)
{
substring_t args[MAX_OPT_ARGS];
int ret = -EINVAL;
int key_cmd;
+ int key_format;
char *p, *keyword;

keyword = strsep(&datablob, " \t");
@@ -142,7 +158,24 @@ static int datablob_parse(char *datablob, char **master_desc,
}
key_cmd = match_token(keyword, key_tokens, args);

- *master_desc = strsep(&datablob, " \t");
+ /* Get optional format: default */
+ p = strsep(&datablob, " \t");
+ if (!p) {
+ pr_err("encrypted_key: insufficient parameters specified");
+ return ret;
+ }
+
+ key_format = match_token(p, key_format_tokens, args);
+ switch (key_format) {
+ case Opt_default:
+ *format = p;
+ *master_desc = strsep(&datablob, " \t");
+ break;
+ case Opt_error:
+ *master_desc = p;
+ break;
+ }
+
if (!*master_desc) {
pr_err("encrypted_key: master key parameter is missing");
goto out;
@@ -219,8 +252,8 @@ static char *datablob_format(struct encrypted_key_payload *epayload,
ascii_buf[asciiblob_len] = '\0';

/* copy datablob master_desc and datalen strings */
- len = sprintf(ascii_buf, "%s %s ", epayload->master_desc,
- epayload->datalen);
+ len = sprintf(ascii_buf, "%s %s %s ", epayload->format,
+ epayload->master_desc, epayload->datalen);

/* convert the hex encoded iv, encrypted-data and HMAC to ascii */
bufp = &ascii_buf[len];
@@ -461,9 +494,9 @@ static int datablob_hmac_append(struct encrypted_key_payload *epayload,
if (ret < 0)
goto out;

- digest = epayload->master_desc + epayload->datablob_len;
+ digest = epayload->format + epayload->datablob_len;
ret = calc_hmac(digest, derived_key, sizeof derived_key,
- epayload->master_desc, epayload->datablob_len);
+ epayload->format, epayload->datablob_len);
if (!ret)
dump_hmac(NULL, digest, HASH_SIZE);
out:
@@ -472,26 +505,35 @@ out:

/* verify HMAC before decrypting encrypted key */
static int datablob_hmac_verify(struct encrypted_key_payload *epayload,
- const u8 *master_key, size_t master_keylen)
+ const u8 *format, const u8 *master_key,
+ size_t master_keylen)
{
u8 derived_key[HASH_SIZE];
u8 digest[HASH_SIZE];
int ret;
+ char *p;
+ unsigned short len;

ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen);
if (ret < 0)
goto out;

- ret = calc_hmac(digest, derived_key, sizeof derived_key,
- epayload->master_desc, epayload->datablob_len);
+ len = epayload->datablob_len;
+ if (!format) {
+ p = epayload->master_desc;
+ len -= strlen(epayload->format) + 1;
+ } else
+ p = epayload->format;
+
+ ret = calc_hmac(digest, derived_key, sizeof derived_key, p, len);
if (ret < 0)
goto out;
- ret = memcmp(digest, epayload->master_desc + epayload->datablob_len,
+ ret = memcmp(digest, epayload->format + epayload->datablob_len,
sizeof digest);
if (ret) {
ret = -EINVAL;
dump_hmac("datablob",
- epayload->master_desc + epayload->datablob_len,
+ epayload->format + epayload->datablob_len,
HASH_SIZE);
dump_hmac("calc", digest, HASH_SIZE);
}
@@ -536,13 +578,16 @@ out:

/* Allocate memory for decrypted key and datablob. */
static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
+ const char *format,
const char *master_desc,
const char *datalen)
{
struct encrypted_key_payload *epayload = NULL;
unsigned short datablob_len;
unsigned short decrypted_datalen;
+ unsigned short payload_datalen;
unsigned int encrypted_datalen;
+ unsigned int format_len;
long dlen;
int ret;

@@ -550,29 +595,32 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
if (ret < 0 || dlen < MIN_DATA_SIZE || dlen > MAX_DATA_SIZE)
return ERR_PTR(-EINVAL);

+ format_len = (!format) ? strlen(key_format_default) : strlen(format);
decrypted_datalen = dlen;
+ payload_datalen = decrypted_datalen;
encrypted_datalen = roundup(decrypted_datalen, blksize);

- datablob_len = strlen(master_desc) + 1 + strlen(datalen) + 1
- + ivsize + 1 + encrypted_datalen;
+ datablob_len = format_len + 1 + strlen(master_desc) + 1
+ + strlen(datalen) + 1 + ivsize + 1 + encrypted_datalen;

- ret = key_payload_reserve(key, decrypted_datalen + datablob_len
+ ret = key_payload_reserve(key, payload_datalen + datablob_len
+ HASH_SIZE + 1);
if (ret < 0)
return ERR_PTR(ret);

- epayload = kzalloc(sizeof(*epayload) + decrypted_datalen +
+ epayload = kzalloc(sizeof(*epayload) + payload_datalen +
datablob_len + HASH_SIZE + 1, GFP_KERNEL);
if (!epayload)
return ERR_PTR(-ENOMEM);

+ epayload->payload_datalen = payload_datalen;
epayload->decrypted_datalen = decrypted_datalen;
epayload->datablob_len = datablob_len;
return epayload;
}

static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
- const char *hex_encoded_iv)
+ const char *format, const char *hex_encoded_iv)
{
struct key *mkey;
u8 derived_key[HASH_SIZE];
@@ -593,14 +641,14 @@ static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
hex2bin(epayload->iv, hex_encoded_iv, ivsize);
hex2bin(epayload->encrypted_data, hex_encoded_data, encrypted_datalen);

- hmac = epayload->master_desc + epayload->datablob_len;
+ hmac = epayload->format + epayload->datablob_len;
hex2bin(hmac, hex_encoded_data + (encrypted_datalen * 2), HASH_SIZE);

mkey = request_master_key(epayload, &master_key, &master_keylen);
if (IS_ERR(mkey))
return PTR_ERR(mkey);

- ret = datablob_hmac_verify(epayload, master_key, master_keylen);
+ ret = datablob_hmac_verify(epayload, format, master_key, master_keylen);
if (ret < 0) {
pr_err("encrypted_key: bad hmac (%d)", ret);
goto out;
@@ -620,14 +668,23 @@ out:
}

static void __ekey_init(struct encrypted_key_payload *epayload,
- const char *master_desc, const char *datalen)
+ const char *format, const char *master_desc,
+ const char *datalen)
{
- epayload->master_desc = epayload->decrypted_data
- + epayload->decrypted_datalen;
+ unsigned int format_len;
+
+ format_len = (!format) ? strlen(key_format_default) : strlen(format);
+ epayload->format = epayload->payload_data + epayload->payload_datalen;
+ epayload->master_desc = epayload->format + format_len + 1;
epayload->datalen = epayload->master_desc + strlen(master_desc) + 1;
epayload->iv = epayload->datalen + strlen(datalen) + 1;
epayload->encrypted_data = epayload->iv + ivsize + 1;
+ epayload->decrypted_data = epayload->payload_data;

+ if (!format)
+ memcpy(epayload->format, key_format_default, format_len);
+ else
+ memcpy(epayload->format, format, format_len);
memcpy(epayload->master_desc, master_desc, strlen(master_desc));
memcpy(epayload->datalen, datalen, strlen(datalen));
}
@@ -639,19 +696,19 @@ static void __ekey_init(struct encrypted_key_payload *epayload,
* itself. For an old key, decrypt the hex encoded data.
*/
static int encrypted_init(struct encrypted_key_payload *epayload,
- const char *master_desc, const char *datalen,
- const char *hex_encoded_iv)
+ const char *format, const char *master_desc,
+ const char *datalen, const char *hex_encoded_iv)
{
int ret = 0;

- __ekey_init(epayload, master_desc, datalen);
+ __ekey_init(epayload, format, master_desc, datalen);
if (!hex_encoded_iv) {
get_random_bytes(epayload->iv, ivsize);

get_random_bytes(epayload->decrypted_data,
epayload->decrypted_datalen);
} else
- ret = encrypted_key_decrypt(epayload, hex_encoded_iv);
+ ret = encrypted_key_decrypt(epayload, format, hex_encoded_iv);
return ret;
}

@@ -668,6 +725,7 @@ static int encrypted_instantiate(struct key *key, const void *data,
{
struct encrypted_key_payload *epayload = NULL;
char *datablob = NULL;
+ const char *format = NULL;
char *master_desc = NULL;
char *decrypted_datalen = NULL;
char *hex_encoded_iv = NULL;
@@ -681,17 +739,18 @@ static int encrypted_instantiate(struct key *key, const void *data,
return -ENOMEM;
datablob[datalen] = 0;
memcpy(datablob, data, datalen);
- ret = datablob_parse(datablob, &master_desc, &decrypted_datalen,
- &hex_encoded_iv);
+ ret = datablob_parse(datablob, &format, &master_desc,
+ &decrypted_datalen, &hex_encoded_iv);
if (ret < 0)
goto out;

- epayload = encrypted_key_alloc(key, master_desc, decrypted_datalen);
+ epayload = encrypted_key_alloc(key, format, master_desc,
+ decrypted_datalen);
if (IS_ERR(epayload)) {
ret = PTR_ERR(epayload);
goto out;
}
- ret = encrypted_init(epayload, master_desc, decrypted_datalen,
+ ret = encrypted_init(epayload, format, master_desc, decrypted_datalen,
hex_encoded_iv);
if (ret < 0) {
kfree(epayload);
@@ -728,6 +787,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
struct encrypted_key_payload *new_epayload;
char *buf;
char *new_master_desc = NULL;
+ const char *format = NULL;
int ret = 0;

if (datalen <= 0 || datalen > 32767 || !data)
@@ -739,7 +799,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)

buf[datalen] = 0;
memcpy(buf, data, datalen);
- ret = datablob_parse(buf, &new_master_desc, NULL, NULL);
+ ret = datablob_parse(buf, &format, &new_master_desc, NULL, NULL);
if (ret < 0)
goto out;

@@ -747,18 +807,19 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
if (ret < 0)
goto out;

- new_epayload = encrypted_key_alloc(key, new_master_desc,
- epayload->datalen);
+ new_epayload = encrypted_key_alloc(key, epayload->format,
+ new_master_desc, epayload->datalen);
if (IS_ERR(new_epayload)) {
ret = PTR_ERR(new_epayload);
goto out;
}

- __ekey_init(new_epayload, new_master_desc, epayload->datalen);
+ __ekey_init(new_epayload, epayload->format, new_master_desc,
+ epayload->datalen);

memcpy(new_epayload->iv, epayload->iv, ivsize);
- memcpy(new_epayload->decrypted_data, epayload->decrypted_data,
- epayload->decrypted_datalen);
+ memcpy(new_epayload->payload_data, epayload->payload_data,
+ epayload->payload_datalen);

rcu_assign_pointer(key->payload.data, new_epayload);
call_rcu(&epayload->rcu, encrypted_rcu_free);





To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Similar topics