aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/keys/Makefile2
-rw-r--r--security/keys/ecryptfs_format.c81
-rw-r--r--security/keys/ecryptfs_format.h30
-rw-r--r--security/keys/encrypted.c75
4 files changed, 180 insertions, 8 deletions
diff --git a/security/keys/Makefile b/security/keys/Makefile
index 1bf090a885fe..b34cc6ee6900 100644
--- a/security/keys/Makefile
+++ b/security/keys/Makefile
@@ -14,7 +14,7 @@ obj-y := \
14 user_defined.o 14 user_defined.o
15 15
16obj-$(CONFIG_TRUSTED_KEYS) += trusted.o 16obj-$(CONFIG_TRUSTED_KEYS) += trusted.o
17obj-$(CONFIG_ENCRYPTED_KEYS) += encrypted.o 17obj-$(CONFIG_ENCRYPTED_KEYS) += ecryptfs_format.o encrypted.o
18obj-$(CONFIG_KEYS_COMPAT) += compat.o 18obj-$(CONFIG_KEYS_COMPAT) += compat.o
19obj-$(CONFIG_PROC_FS) += proc.o 19obj-$(CONFIG_PROC_FS) += proc.o
20obj-$(CONFIG_SYSCTL) += sysctl.o 20obj-$(CONFIG_SYSCTL) += sysctl.o
diff --git a/security/keys/ecryptfs_format.c b/security/keys/ecryptfs_format.c
new file mode 100644
index 000000000000..6daa3b6ff9ed
--- /dev/null
+++ b/security/keys/ecryptfs_format.c
@@ -0,0 +1,81 @@
1/*
2 * ecryptfs_format.c: helper functions for the encrypted key type
3 *
4 * Copyright (C) 2006 International Business Machines Corp.
5 * Copyright (C) 2010 Politecnico di Torino, Italy
6 * TORSEC group -- http://security.polito.it
7 *
8 * Authors:
9 * Michael A. Halcrow <mahalcro@us.ibm.com>
10 * Tyler Hicks <tyhicks@ou.edu>
11 * Roberto Sassu <roberto.sassu@polito.it>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation, version 2 of the License.
16 */
17
18#include <linux/module.h>
19#include "ecryptfs_format.h"
20
21u8 *ecryptfs_get_auth_tok_key(struct ecryptfs_auth_tok *auth_tok)
22{
23 return auth_tok->token.password.session_key_encryption_key;
24}
25EXPORT_SYMBOL(ecryptfs_get_auth_tok_key);
26
27/*
28 * ecryptfs_get_versions()
29 *
30 * Source code taken from the software 'ecryptfs-utils' version 83.
31 *
32 */
33void ecryptfs_get_versions(int *major, int *minor, int *file_version)
34{
35 *major = ECRYPTFS_VERSION_MAJOR;
36 *minor = ECRYPTFS_VERSION_MINOR;
37 if (file_version)
38 *file_version = ECRYPTFS_SUPPORTED_FILE_VERSION;
39}
40EXPORT_SYMBOL(ecryptfs_get_versions);
41
42/*
43 * ecryptfs_fill_auth_tok - fill the ecryptfs_auth_tok structure
44 *
45 * Fill the ecryptfs_auth_tok structure with required ecryptfs data.
46 * The source code is inspired to the original function generate_payload()
47 * shipped with the software 'ecryptfs-utils' version 83.
48 *
49 */
50int ecryptfs_fill_auth_tok(struct ecryptfs_auth_tok *auth_tok,
51 const char *key_desc)
52{
53 int major, minor;
54
55 ecryptfs_get_versions(&major, &minor, NULL);
56 auth_tok->version = (((uint16_t)(major << 8) & 0xFF00)
57 | ((uint16_t)minor & 0x00FF));
58 auth_tok->token_type = ECRYPTFS_PASSWORD;
59 strncpy((char *)auth_tok->token.password.signature, key_desc,
60 ECRYPTFS_PASSWORD_SIG_SIZE);
61 auth_tok->token.password.session_key_encryption_key_bytes =
62 ECRYPTFS_MAX_KEY_BYTES;
63 /*
64 * Removed auth_tok->token.password.salt and
65 * auth_tok->token.password.session_key_encryption_key
66 * initialization from the original code
67 */
68 /* TODO: Make the hash parameterizable via policy */
69 auth_tok->token.password.flags |=
70 ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET;
71 /* The kernel code will encrypt the session key. */
72 auth_tok->session_key.encrypted_key[0] = 0;
73 auth_tok->session_key.encrypted_key_size = 0;
74 /* Default; subject to change by kernel eCryptfs */
75 auth_tok->token.password.hash_algo = PGP_DIGEST_ALGO_SHA512;
76 auth_tok->token.password.flags &= ~(ECRYPTFS_PERSISTENT_PASSWORD);
77 return 0;
78}
79EXPORT_SYMBOL(ecryptfs_fill_auth_tok);
80
81MODULE_LICENSE("GPL");
diff --git a/security/keys/ecryptfs_format.h b/security/keys/ecryptfs_format.h
new file mode 100644
index 000000000000..40294de238bb
--- /dev/null
+++ b/security/keys/ecryptfs_format.h
@@ -0,0 +1,30 @@
1/*
2 * ecryptfs_format.h: helper functions for the encrypted key type
3 *
4 * Copyright (C) 2006 International Business Machines Corp.
5 * Copyright (C) 2010 Politecnico di Torino, Italy
6 * TORSEC group -- http://security.polito.it
7 *
8 * Authors:
9 * Michael A. Halcrow <mahalcro@us.ibm.com>
10 * Tyler Hicks <tyhicks@ou.edu>
11 * Roberto Sassu <roberto.sassu@polito.it>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation, version 2 of the License.
16 */
17
18#ifndef __KEYS_ECRYPTFS_H
19#define __KEYS_ECRYPTFS_H
20
21#include <linux/ecryptfs.h>
22
23#define PGP_DIGEST_ALGO_SHA512 10
24
25u8 *ecryptfs_get_auth_tok_key(struct ecryptfs_auth_tok *auth_tok);
26void ecryptfs_get_versions(int *major, int *minor, int *file_version);
27int ecryptfs_fill_auth_tok(struct ecryptfs_auth_tok *auth_tok,
28 const char *key_desc);
29
30#endif /* __KEYS_ECRYPTFS_H */
diff --git a/security/keys/encrypted.c b/security/keys/encrypted.c
index 89981c987ba7..e7eca9ec4c65 100644
--- a/security/keys/encrypted.c
+++ b/security/keys/encrypted.c
@@ -29,11 +29,13 @@
29#include <linux/rcupdate.h> 29#include <linux/rcupdate.h>
30#include <linux/scatterlist.h> 30#include <linux/scatterlist.h>
31#include <linux/crypto.h> 31#include <linux/crypto.h>
32#include <linux/ctype.h>
32#include <crypto/hash.h> 33#include <crypto/hash.h>
33#include <crypto/sha.h> 34#include <crypto/sha.h>
34#include <crypto/aes.h> 35#include <crypto/aes.h>
35 36
36#include "encrypted.h" 37#include "encrypted.h"
38#include "ecryptfs_format.h"
37 39
38static const char KEY_TRUSTED_PREFIX[] = "trusted:"; 40static const char KEY_TRUSTED_PREFIX[] = "trusted:";
39static const char KEY_USER_PREFIX[] = "user:"; 41static const char KEY_USER_PREFIX[] = "user:";
@@ -41,11 +43,13 @@ static const char hash_alg[] = "sha256";
41static const char hmac_alg[] = "hmac(sha256)"; 43static const char hmac_alg[] = "hmac(sha256)";
42static const char blkcipher_alg[] = "cbc(aes)"; 44static const char blkcipher_alg[] = "cbc(aes)";
43static const char key_format_default[] = "default"; 45static const char key_format_default[] = "default";
46static const char key_format_ecryptfs[] = "ecryptfs";
44static unsigned int ivsize; 47static unsigned int ivsize;
45static int blksize; 48static int blksize;
46 49
47#define KEY_TRUSTED_PREFIX_LEN (sizeof (KEY_TRUSTED_PREFIX) - 1) 50#define KEY_TRUSTED_PREFIX_LEN (sizeof (KEY_TRUSTED_PREFIX) - 1)
48#define KEY_USER_PREFIX_LEN (sizeof (KEY_USER_PREFIX) - 1) 51#define KEY_USER_PREFIX_LEN (sizeof (KEY_USER_PREFIX) - 1)
52#define KEY_ECRYPTFS_DESC_LEN 16
49#define HASH_SIZE SHA256_DIGEST_SIZE 53#define HASH_SIZE SHA256_DIGEST_SIZE
50#define MAX_DATA_SIZE 4096 54#define MAX_DATA_SIZE 4096
51#define MIN_DATA_SIZE 20 55#define MIN_DATA_SIZE 20
@@ -63,11 +67,12 @@ enum {
63}; 67};
64 68
65enum { 69enum {
66 Opt_error = -1, Opt_default 70 Opt_error = -1, Opt_default, Opt_ecryptfs
67}; 71};
68 72
69static const match_table_t key_format_tokens = { 73static const match_table_t key_format_tokens = {
70 {Opt_default, "default"}, 74 {Opt_default, "default"},
75 {Opt_ecryptfs, "ecryptfs"},
71 {Opt_error, NULL} 76 {Opt_error, NULL}
72}; 77};
73 78
@@ -95,6 +100,34 @@ static int aes_get_sizes(void)
95} 100}
96 101
97/* 102/*
103 * valid_ecryptfs_desc - verify the description of a new/loaded encrypted key
104 *
105 * The description of a encrypted key with format 'ecryptfs' must contain
106 * exactly 16 hexadecimal characters.
107 *
108 */
109static int valid_ecryptfs_desc(const char *ecryptfs_desc)
110{
111 int i;
112
113 if (strlen(ecryptfs_desc) != KEY_ECRYPTFS_DESC_LEN) {
114 pr_err("encrypted_key: key description must be %d hexadecimal "
115 "characters long\n", KEY_ECRYPTFS_DESC_LEN);
116 return -EINVAL;
117 }
118
119 for (i = 0; i < KEY_ECRYPTFS_DESC_LEN; i++) {
120 if (!isxdigit(ecryptfs_desc[i])) {
121 pr_err("encrypted_key: key description must contain "
122 "only hexadecimal characters\n");
123 return -EINVAL;
124 }
125 }
126
127 return 0;
128}
129
130/*
98 * valid_master_desc - verify the 'key-type:desc' of a new/updated master-key 131 * valid_master_desc - verify the 'key-type:desc' of a new/updated master-key
99 * 132 *
100 * key-type:= "trusted:" | "user:" 133 * key-type:= "trusted:" | "user:"
@@ -158,7 +191,7 @@ static int datablob_parse(char *datablob, const char **format,
158 } 191 }
159 key_cmd = match_token(keyword, key_tokens, args); 192 key_cmd = match_token(keyword, key_tokens, args);
160 193
161 /* Get optional format: default */ 194 /* Get optional format: default | ecryptfs */
162 p = strsep(&datablob, " \t"); 195 p = strsep(&datablob, " \t");
163 if (!p) { 196 if (!p) {
164 pr_err("encrypted_key: insufficient parameters specified\n"); 197 pr_err("encrypted_key: insufficient parameters specified\n");
@@ -167,6 +200,7 @@ static int datablob_parse(char *datablob, const char **format,
167 200
168 key_format = match_token(p, key_format_tokens, args); 201 key_format = match_token(p, key_format_tokens, args);
169 switch (key_format) { 202 switch (key_format) {
203 case Opt_ecryptfs:
170 case Opt_default: 204 case Opt_default:
171 *format = p; 205 *format = p;
172 *master_desc = strsep(&datablob, " \t"); 206 *master_desc = strsep(&datablob, " \t");
@@ -601,6 +635,17 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
601 format_len = (!format) ? strlen(key_format_default) : strlen(format); 635 format_len = (!format) ? strlen(key_format_default) : strlen(format);
602 decrypted_datalen = dlen; 636 decrypted_datalen = dlen;
603 payload_datalen = decrypted_datalen; 637 payload_datalen = decrypted_datalen;
638 if (format && !strcmp(format, key_format_ecryptfs)) {
639 if (dlen != ECRYPTFS_MAX_KEY_BYTES) {
640 pr_err("encrypted_key: keylen for the ecryptfs format "
641 "must be equal to %d bytes\n",
642 ECRYPTFS_MAX_KEY_BYTES);
643 return ERR_PTR(-EINVAL);
644 }
645 decrypted_datalen = ECRYPTFS_MAX_KEY_BYTES;
646 payload_datalen = sizeof(struct ecryptfs_auth_tok);
647 }
648
604 encrypted_datalen = roundup(decrypted_datalen, blksize); 649 encrypted_datalen = roundup(decrypted_datalen, blksize);
605 650
606 datablob_len = format_len + 1 + strlen(master_desc) + 1 651 datablob_len = format_len + 1 + strlen(master_desc) + 1
@@ -686,8 +731,14 @@ static void __ekey_init(struct encrypted_key_payload *epayload,
686 731
687 if (!format) 732 if (!format)
688 memcpy(epayload->format, key_format_default, format_len); 733 memcpy(epayload->format, key_format_default, format_len);
689 else 734 else {
735 if (!strcmp(format, key_format_ecryptfs))
736 epayload->decrypted_data =
737 ecryptfs_get_auth_tok_key((struct ecryptfs_auth_tok *)epayload->payload_data);
738
690 memcpy(epayload->format, format, format_len); 739 memcpy(epayload->format, format, format_len);
740 }
741
691 memcpy(epayload->master_desc, master_desc, strlen(master_desc)); 742 memcpy(epayload->master_desc, master_desc, strlen(master_desc));
692 memcpy(epayload->datalen, datalen, strlen(datalen)); 743 memcpy(epayload->datalen, datalen, strlen(datalen));
693} 744}
@@ -699,11 +750,21 @@ static void __ekey_init(struct encrypted_key_payload *epayload,
699 * itself. For an old key, decrypt the hex encoded data. 750 * itself. For an old key, decrypt the hex encoded data.
700 */ 751 */
701static int encrypted_init(struct encrypted_key_payload *epayload, 752static int encrypted_init(struct encrypted_key_payload *epayload,
702 const char *format, const char *master_desc, 753 const char *key_desc, const char *format,
703 const char *datalen, const char *hex_encoded_iv) 754 const char *master_desc, const char *datalen,
755 const char *hex_encoded_iv)
704{ 756{
705 int ret = 0; 757 int ret = 0;
706 758
759 if (format && !strcmp(format, key_format_ecryptfs)) {
760 ret = valid_ecryptfs_desc(key_desc);
761 if (ret < 0)
762 return ret;
763
764 ecryptfs_fill_auth_tok((struct ecryptfs_auth_tok *)epayload->payload_data,
765 key_desc);
766 }
767
707 __ekey_init(epayload, format, master_desc, datalen); 768 __ekey_init(epayload, format, master_desc, datalen);
708 if (!hex_encoded_iv) { 769 if (!hex_encoded_iv) {
709 get_random_bytes(epayload->iv, ivsize); 770 get_random_bytes(epayload->iv, ivsize);
@@ -753,8 +814,8 @@ static int encrypted_instantiate(struct key *key, const void *data,
753 ret = PTR_ERR(epayload); 814 ret = PTR_ERR(epayload);
754 goto out; 815 goto out;
755 } 816 }
756 ret = encrypted_init(epayload, format, master_desc, decrypted_datalen, 817 ret = encrypted_init(epayload, key->description, format, master_desc,
757 hex_encoded_iv); 818 decrypted_datalen, hex_encoded_iv);
758 if (ret < 0) { 819 if (ret < 0) {
759 kfree(epayload); 820 kfree(epayload);
760 goto out; 821 goto out;