aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys')
-rw-r--r--security/keys/Makefile1
-rw-r--r--security/keys/trusted_defined.c1151
-rw-r--r--security/keys/trusted_defined.h134
3 files changed, 1286 insertions, 0 deletions
diff --git a/security/keys/Makefile b/security/keys/Makefile
index 74d5447d7df7..fcb107020b4a 100644
--- a/security/keys/Makefile
+++ b/security/keys/Makefile
@@ -13,6 +13,7 @@ obj-y := \
13 request_key_auth.o \ 13 request_key_auth.o \
14 user_defined.o 14 user_defined.o
15 15
16obj-$(CONFIG_TRUSTED_KEYS) += trusted_defined.o
16obj-$(CONFIG_KEYS_COMPAT) += compat.o 17obj-$(CONFIG_KEYS_COMPAT) += compat.o
17obj-$(CONFIG_PROC_FS) += proc.o 18obj-$(CONFIG_PROC_FS) += proc.o
18obj-$(CONFIG_SYSCTL) += sysctl.o 19obj-$(CONFIG_SYSCTL) += sysctl.o
diff --git a/security/keys/trusted_defined.c b/security/keys/trusted_defined.c
new file mode 100644
index 000000000000..1bec72e7596d
--- /dev/null
+++ b/security/keys/trusted_defined.c
@@ -0,0 +1,1151 @@
1/*
2 * Copyright (C) 2010 IBM Corporation
3 *
4 * Author:
5 * David Safford <safford@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, version 2 of the License.
10 *
11 * See Documentation/keys-trusted-encrypted.txt
12 */
13
14#include <linux/uaccess.h>
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/slab.h>
18#include <linux/parser.h>
19#include <linux/string.h>
20#include <keys/user-type.h>
21#include <keys/trusted-type.h>
22#include <linux/key-type.h>
23#include <linux/rcupdate.h>
24#include <linux/crypto.h>
25#include <crypto/hash.h>
26#include <crypto/sha.h>
27#include <linux/capability.h>
28#include <linux/tpm.h>
29#include <linux/tpm_command.h>
30
31#include "trusted_defined.h"
32
33static const char hmac_alg[] = "hmac(sha1)";
34static const char hash_alg[] = "sha1";
35
36struct sdesc {
37 struct shash_desc shash;
38 char ctx[];
39};
40
41static struct crypto_shash *hashalg;
42static struct crypto_shash *hmacalg;
43
44static struct sdesc *init_sdesc(struct crypto_shash *alg)
45{
46 struct sdesc *sdesc;
47 int size;
48
49 size = sizeof(struct shash_desc) + crypto_shash_descsize(alg);
50 sdesc = kmalloc(size, GFP_KERNEL);
51 if (!sdesc)
52 return ERR_PTR(-ENOMEM);
53 sdesc->shash.tfm = alg;
54 sdesc->shash.flags = 0x0;
55 return sdesc;
56}
57
58static int TSS_sha1(const unsigned char *data, const unsigned int datalen,
59 unsigned char *digest)
60{
61 struct sdesc *sdesc;
62 int ret;
63
64 sdesc = init_sdesc(hashalg);
65 if (IS_ERR(sdesc)) {
66 pr_info("trusted_key: can't alloc %s\n", hash_alg);
67 return PTR_ERR(sdesc);
68 }
69
70 ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest);
71 kfree(sdesc);
72 return ret;
73}
74
75static int TSS_rawhmac(unsigned char *digest, const unsigned char *key,
76 const unsigned int keylen, ...)
77{
78 struct sdesc *sdesc;
79 va_list argp;
80 unsigned int dlen;
81 unsigned char *data;
82 int ret;
83
84 sdesc = init_sdesc(hmacalg);
85 if (IS_ERR(sdesc)) {
86 pr_info("trusted_key: can't alloc %s\n", hmac_alg);
87 return PTR_ERR(sdesc);
88 }
89
90 ret = crypto_shash_setkey(hmacalg, key, keylen);
91 if (ret < 0)
92 goto out;
93 ret = crypto_shash_init(&sdesc->shash);
94 if (ret < 0)
95 goto out;
96
97 va_start(argp, keylen);
98 for (;;) {
99 dlen = va_arg(argp, unsigned int);
100 if (dlen == 0)
101 break;
102 data = va_arg(argp, unsigned char *);
103 if (data == NULL)
104 return -EINVAL;
105 ret = crypto_shash_update(&sdesc->shash, data, dlen);
106 if (ret < 0)
107 goto out;
108 }
109 va_end(argp);
110 ret = crypto_shash_final(&sdesc->shash, digest);
111out:
112 kfree(sdesc);
113 return ret;
114}
115
116/*
117 * calculate authorization info fields to send to TPM
118 */
119static uint32_t TSS_authhmac(unsigned char *digest, const unsigned char *key,
120 const unsigned int keylen, unsigned char *h1,
121 unsigned char *h2, unsigned char h3, ...)
122{
123 unsigned char paramdigest[SHA1_DIGEST_SIZE];
124 struct sdesc *sdesc;
125 unsigned int dlen;
126 unsigned char *data;
127 unsigned char c;
128 int ret;
129 va_list argp;
130
131 sdesc = init_sdesc(hashalg);
132 if (IS_ERR(sdesc)) {
133 pr_info("trusted_key: can't alloc %s\n", hash_alg);
134 return PTR_ERR(sdesc);
135 }
136
137 c = h3;
138 ret = crypto_shash_init(&sdesc->shash);
139 if (ret < 0)
140 goto out;
141 va_start(argp, h3);
142 for (;;) {
143 dlen = va_arg(argp, unsigned int);
144 if (dlen == 0)
145 break;
146 data = va_arg(argp, unsigned char *);
147 ret = crypto_shash_update(&sdesc->shash, data, dlen);
148 if (ret < 0)
149 goto out;
150 }
151 va_end(argp);
152 ret = crypto_shash_final(&sdesc->shash, paramdigest);
153 if (!ret)
154 TSS_rawhmac(digest, key, keylen, SHA1_DIGEST_SIZE,
155 paramdigest, TPM_NONCE_SIZE, h1,
156 TPM_NONCE_SIZE, h2, 1, &c, 0, 0);
157out:
158 kfree(sdesc);
159 return ret;
160}
161
162/*
163 * verify the AUTH1_COMMAND (Seal) result from TPM
164 */
165static uint32_t TSS_checkhmac1(unsigned char *buffer,
166 const uint32_t command,
167 const unsigned char *ononce,
168 const unsigned char *key,
169 const unsigned int keylen, ...)
170{
171 uint32_t bufsize;
172 uint16_t tag;
173 uint32_t ordinal;
174 uint32_t result;
175 unsigned char *enonce;
176 unsigned char *continueflag;
177 unsigned char *authdata;
178 unsigned char testhmac[SHA1_DIGEST_SIZE];
179 unsigned char paramdigest[SHA1_DIGEST_SIZE];
180 struct sdesc *sdesc;
181 unsigned int dlen;
182 unsigned int dpos;
183 va_list argp;
184 int ret;
185
186 bufsize = LOAD32(buffer, TPM_SIZE_OFFSET);
<