summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlimeng-linux <Meng.Li@windriver.com>2017-09-02 10:16:57 +0800
committerLans Zhang <lans.zhang2008@gmail.com>2017-09-02 10:16:57 +0800
commit7f72300c2359539d029aca45eadd7ecdc04b7a1c (patch)
tree57c6a2504b7d4320e9814bef2f29c67a4cc5d8f0
parent49fadf7ef0925917c42104cfc9e75bd4d9753921 (diff)
downloadmeta-secure-core-7f72300c2359539d029aca45eadd7ecdc04b7a1c.tar.gz
tpm : openssl-tpm-engine: parse an encrypted TPM key password from env (#15)
when openssl-tpm-engine lib is used on an unattended device, there is no way to input TPM key password. So add this feature to support parse an encrypted(AES algorithm) TPM key password from env. The default decrypting AES password and salt is set in bb file. When we create a TPM key(TSS format), generate a 8 bytes random data as its password, and then we need to encrypt the password with the same AES password and salt in bb file. At last, we set a env as below: export TPM_KEY_ENC_PW=xxxxxxxx "xxxxxxxx" is the encrypted TPM key password for libtpm.so. Signed-off-by: Meng Li <Meng.Li@windriver.com>
-rw-r--r--meta-tpm/recipes-tpm/openssl-tpm-engine/files/0005-tpm-openssl-tpm-engine-parse-an-encrypted-TPM-key-pa.patch274
-rw-r--r--meta-tpm/recipes-tpm/openssl-tpm-engine/openssl-tpm-engine_git.bb18
2 files changed, 285 insertions, 7 deletions
diff --git a/meta-tpm/recipes-tpm/openssl-tpm-engine/files/0005-tpm-openssl-tpm-engine-parse-an-encrypted-TPM-key-pa.patch b/meta-tpm/recipes-tpm/openssl-tpm-engine/files/0005-tpm-openssl-tpm-engine-parse-an-encrypted-TPM-key-pa.patch
new file mode 100644
index 0000000..0301308
--- /dev/null
+++ b/meta-tpm/recipes-tpm/openssl-tpm-engine/files/0005-tpm-openssl-tpm-engine-parse-an-encrypted-TPM-key-pa.patch
@@ -0,0 +1,274 @@
1From 889639aed890d03a47d9c575280cc785ecc28380 Mon Sep 17 00:00:00 2001
2From: Limeng <Meng.Li@windriver.com>
3Date: Tue, 22 Aug 2017 13:02:51 +0800
4Subject: [PATCH] tpm : openssl-tpm-engine: parse an encrypted TPM key password
5 from env
6
7when openssl-tpm-engine lib is used on an unattended device, there is no
8way to input TPM key password. So add this feature to support parse an
9encrypted(AES algorithm) TPM key password from env.
10The default decrypting AES password and salt is set in bb file.
11When we create a TPM key(TSS format), generate a 8 bytes random data
12as its password, and then we need to encrypt the password with the same
13AES password and salt in bb file.
14At last, we set a env as below:
15export TPM_KEY_ENC_PW=xxxxxxxx
16"xxxxxxxx" is the encrypted TPM key password for libtpm.so.
17
18Signed-off-by: Meng Li <Meng.Li@windriver.com>
19---
20 e_tpm.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++--------------
21 e_tpm.h | 4 +--
22 e_tpm_err.c | 4 +--
23 3 files changed, 89 insertions(+), 29 deletions(-)
24
25diff --git a/e_tpm.c b/e_tpm.c
26index 11bf74b..ee86a3a 100644
27--- a/e_tpm.c
28+++ b/e_tpm.c
29@@ -275,7 +275,7 @@ static int tpm_decode_base64(unsigned char *indata,
30 return 0;
31 }
32
33-static int tpm_decrypt_srk_pw(unsigned char *indata, int in_len,
34+static int tpm_decrypt_pw(unsigned char *indata, int in_len,
35 unsigned char *outdata,
36 int *out_len)
37 {
38@@ -288,35 +288,35 @@ static int tpm_decrypt_srk_pw(unsigned char *indata, int in_len,
39 const EVP_MD *dgst = NULL;
40 EVP_CIPHER_CTX *ctx = NULL;
41
42- if (sizeof(SRK_DEC_SALT) - 1 > PKCS5_SALT_LEN) {
43- TSSerr(TPM_F_TPM_DECRYPT_SRK_PW, TPM_R_DECRYPT_SRK_PW_FAILED);
44+ if (sizeof(DEC_SALT) - 1 > PKCS5_SALT_LEN) {
45+ TSSerr(TPM_F_TPM_DECRYPT_PW, TPM_R_DECRYPT_PW_FAILED);
46 return 1;
47 }
48
49- aes_pw = malloc(sizeof(SRK_DEC_PW) - 1);
50+ aes_pw = malloc(sizeof(DEC_PW) - 1);
51 if (aes_pw == NULL) {
52- TSSerr(TPM_F_TPM_DECRYPT_SRK_PW, TPM_R_DECRYPT_SRK_PW_FAILED);
53+ TSSerr(TPM_F_TPM_DECRYPT_PW, TPM_R_DECRYPT_PW_FAILED);
54 return 1;
55 }
56
57 memset(aes_salt, 0x00, sizeof(aes_salt));
58- memcpy(aes_pw, SRK_DEC_PW, sizeof(SRK_DEC_PW) - 1);
59- memcpy(aes_salt, SRK_DEC_SALT, sizeof(SRK_DEC_SALT) - 1);
60+ memcpy(aes_pw, DEC_PW, sizeof(DEC_PW) - 1);
61+ memcpy(aes_salt, DEC_SALT, sizeof(DEC_SALT) - 1);
62
63 cipher = EVP_get_cipherbyname("aes-128-cbc");
64 if (cipher == NULL) {
65- TSSerr(TPM_F_TPM_DECRYPT_SRK_PW, TPM_R_DECRYPT_SRK_PW_FAILED);
66+ TSSerr(TPM_F_TPM_DECRYPT_PW, TPM_R_DECRYPT_PW_FAILED);
67 free(aes_pw);
68 return 1;
69 }
70 dgst = EVP_sha256();
71
72- EVP_BytesToKey(cipher, dgst, aes_salt, (unsigned char *)aes_pw, sizeof(SRK_DEC_PW) - 1, 1, key, iv);
73+ EVP_BytesToKey(cipher, dgst, aes_salt, (unsigned char *)aes_pw, sizeof(DEC_PW) - 1, 1, key, iv);
74
75 ctx = EVP_CIPHER_CTX_new();
76 /* Don't set key or IV right away; we want to check lengths */
77 if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 0)) {
78- TSSerr(TPM_F_TPM_DECRYPT_SRK_PW, TPM_R_DECRYPT_SRK_PW_FAILED);
79+ TSSerr(TPM_F_TPM_DECRYPT_PW, TPM_R_DECRYPT_PW_FAILED);
80 free(aes_pw);
81 return 1;
82 }
83@@ -325,14 +325,14 @@ static int tpm_decrypt_srk_pw(unsigned char *indata, int in_len,
84 OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) == 16);
85
86 if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 0)) {
87- TSSerr(TPM_F_TPM_DECRYPT_SRK_PW, TPM_R_DECRYPT_SRK_PW_FAILED);
88+ TSSerr(TPM_F_TPM_DECRYPT_PW, TPM_R_DECRYPT_PW_FAILED);
89 free(aes_pw);
90 return 1;
91 }
92
93 if (!EVP_CipherUpdate(ctx, dec_data, &dec_data_len, indata, in_len)) {
94 /* Error */
95- TSSerr(TPM_F_TPM_DECRYPT_SRK_PW, TPM_R_DECRYPT_SRK_PW_FAILED);
96+ TSSerr(TPM_F_TPM_DECRYPT_PW, TPM_R_DECRYPT_PW_FAILED);
97 free(aes_pw);
98 EVP_CIPHER_CTX_free(ctx);
99 return 1;
100@@ -340,7 +340,7 @@ static int tpm_decrypt_srk_pw(unsigned char *indata, int in_len,
101
102 if (!EVP_CipherFinal_ex(ctx, dec_data + dec_data_len, &dec_data_lenfinal)) {
103 /* Error */
104- TSSerr(TPM_F_TPM_DECRYPT_SRK_PW, TPM_R_DECRYPT_SRK_PW_FAILED);
105+ TSSerr(TPM_F_TPM_DECRYPT_PW, TPM_R_DECRYPT_PW_FAILED);
106 free(aes_pw);
107 EVP_CIPHER_CTX_free(ctx);
108 return 1;
109@@ -448,8 +448,7 @@ int tpm_load_srk(UI_METHOD *ui, void *cb_data)
110 return 0;
111 }
112
113- if (tpm_decrypt_srk_pw(out_buf, out_len,
114- auth, &authlen)) {
115+ if (tpm_decrypt_pw(out_buf, out_len, auth, &authlen)) {
116 Tspi_Context_CloseObject(hContext, hSRK);
117 free(auth);
118 free(out_buf);
119@@ -460,7 +459,7 @@ int tpm_load_srk(UI_METHOD *ui, void *cb_data)
120 free(out_buf);
121 }
122 #ifdef TPM_SRK_PLAIN_PW
123- else if (NULL != (srkPasswd = getenv("TPM_SRK_PW")) {
124+ else if (NULL != (srkPasswd = getenv("TPM_SRK_PW"))) {
125 if (0 == strcmp(srkPasswd, "#WELLKNOWN#")) {
126 memset(auth, 0, TPM_WELL_KNOWN_KEY_LEN);
127 secretMode = TSS_SECRET_MODE_SHA1;
128@@ -807,6 +806,9 @@ static EVP_PKEY *tpm_engine_load_key(ENGINE *e, const char *key_id,
129 if (authusage) {
130 TSS_HPOLICY hPolicy;
131 BYTE *auth;
132+ char *tpmKeyPasswd = NULL;
133+ int authlen = 0;
134+ TSS_FLAG secretMode = secret_mode;
135
136 if ((auth = calloc(1, 128)) == NULL) {
137 Tspi_Context_CloseObject(hContext, hKey);
138@@ -814,13 +816,71 @@ static EVP_PKEY *tpm_engine_load_key(ENGINE *e, const char *key_id,
139 return NULL;
140 }
141
142- if (!tpm_engine_get_auth(ui, (char *)auth, 128,
143- "TPM Key Password: ",
144- cb_data)) {
145- Tspi_Context_CloseObject(hContext, hKey);
146- free(auth);
147- TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_REQUEST_FAILED);
148- return NULL;
149+ tpmKeyPasswd = getenv("TPM_KEY_ENC_PW");
150+ if (NULL != tpmKeyPasswd) {
151+ int in_len = strlen(tpmKeyPasswd);
152+ int out_len;
153+ unsigned char *out_buf;
154+
155+ if (!in_len || in_len % 4) {
156+ Tspi_Context_CloseObject(hContext, hKey);
157+ free(auth);
158+ TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_REQUEST_FAILED);
159+ return NULL;
160+ }
161+ out_len = in_len * 3 / 4;
162+ out_buf = malloc(out_len);
163+ if (NULL == out_buf) {
164+ Tspi_Context_CloseObject(hContext, hKey);
165+ free(auth);
166+ TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, ERR_R_MALLOC_FAILURE);
167+ return NULL;
168+ }
169+
170+ if (tpm_decode_base64(tpmKeyPasswd, strlen(tpmKeyPasswd),
171+ out_buf, &out_len)) {
172+ Tspi_Context_CloseObject(hContext, hKey);
173+ free(auth);
174+ free(out_buf);
175+ TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_REQUEST_FAILED);
176+ return NULL;
177+ }
178+
179+ if (tpm_decrypt_pw(out_buf, out_len, auth, &authlen)) {
180+ Tspi_Context_CloseObject(hContext, hKey);
181+ free(auth);
182+ free(out_buf);
183+ TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_REQUEST_FAILED);
184+ return 0;
185+ }
186+ secretMode = TSS_SECRET_MODE_PLAIN;
187+ free(out_buf);
188+ }
189+#ifdef TPM_KEY_PLAIN_PW
190+ else if (NULL != (tpmKeyPasswd = getenv("TPM_KEY_PW"))) {
191+ if (0 == strcmp(tpmKeyPasswd, "#WELLKNOWN#")) {
192+ memset(auth, 0, TPM_WELL_KNOWN_KEY_LEN);
193+ secretMode = TSS_SECRET_MODE_SHA1;
194+ authlen = TPM_WELL_KNOWN_KEY_LEN;
195+ } else {
196+ int authbuflen = 128;
197+ memset(auth, 0, authbuflen);
198+ strncpy(auth, tpmKeyPasswd, authbuflen-1);
199+ secretMode = TSS_SECRET_MODE_PLAIN;
200+ authlen = strlen(auth);
201+ }
202+ }
203+#endif
204+ else {
205+ if (!tpm_engine_get_auth(ui, (char *)auth, 128,
206+ "TPM Key Password: ", cb_data)) {
207+ Tspi_Context_CloseObject(hContext, hKey);
208+ free(auth);
209+ TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_REQUEST_FAILED);
210+ return NULL;
211+ }
212+ secretMode = secret_mode;
213+ authlen = strlen(auth);
214 }
215
216 if ((result = Tspi_Context_CreateObject(hContext,
217@@ -842,8 +902,8 @@ static EVP_PKEY *tpm_engine_load_key(ENGINE *e, const char *key_id,
218 }
219
220 if ((result = Tspi_Policy_SetSecret(hPolicy,
221- TSS_SECRET_MODE_PLAIN,
222- strlen((char *)auth), auth))) {
223+ secretMode,
224+ authlen, auth))) {
225 Tspi_Context_CloseObject(hContext, hKey);
226 Tspi_Context_CloseObject(hContext, hPolicy);
227 free(auth);
228diff --git a/e_tpm.h b/e_tpm.h
229index 56ff202..7faf744 100644
230--- a/e_tpm.h
231+++ b/e_tpm.h
232@@ -67,7 +67,7 @@ void ERR_TSS_error(int function, int reason, char *file, int line);
233 #define TPM_F_TPM_ENGINE_GET_AUTH 117
234 #define TPM_F_TPM_CREATE_SRK_POLICY 118
235 #define TPM_F_TPM_DECODE_BASE64 119
236-#define TPM_F_TPM_DECRYPT_SRK_PW 120
237+#define TPM_F_TPM_DECRYPT_PW 120
238
239 /* Reason codes. */
240 #define TPM_R_ALREADY_LOADED 100
241@@ -99,7 +99,7 @@ void ERR_TSS_error(int function, int reason, char *file, int line);
242 #define TPM_R_UI_METHOD_FAILED 126
243 #define TPM_R_UNKNOWN_SECRET_MODE 127
244 #define TPM_R_DECODE_BASE64_FAILED 128
245-#define TPM_R_DECRYPT_SRK_PW_FAILED 129
246+#define TPM_R_DECRYPT_PW_FAILED 129
247
248 /* structure pointed to by the RSA object's app_data pointer */
249 struct rsa_app_data
250diff --git a/e_tpm_err.c b/e_tpm_err.c
251index 439e267..f8ce624 100644
252--- a/e_tpm_err.c
253+++ b/e_tpm_err.c
254@@ -236,7 +236,7 @@ static ERR_STRING_DATA TPM_str_functs[] = {
255 {ERR_PACK(0, TPM_F_TPM_FILL_RSA_OBJECT, 0), "TPM_FILL_RSA_OBJECT"},
256 {ERR_PACK(0, TPM_F_TPM_ENGINE_GET_AUTH, 0), "TPM_ENGINE_GET_AUTH"},
257 {ERR_PACK(0, TPM_F_TPM_DECODE_BASE64, 0), "TPM_DECODE_BASE64"},
258- {ERR_PACK(0, TPM_F_TPM_DECRYPT_SRK_PW, 0), "TPM_DECRYPT_SRK_PW"},
259+ {ERR_PACK(0, TPM_F_TPM_DECRYPT_PW, 0), "TPM_DECRYPT_SRK_PW"},
260 {0, NULL}
261 };
262
263@@ -268,7 +268,7 @@ static ERR_STRING_DATA TPM_str_reasons[] = {
264 {TPM_R_ID_INVALID, "engine id doesn't match"},
265 {TPM_R_UI_METHOD_FAILED, "ui function failed"},
266 {TPM_R_DECODE_BASE64_FAILED, "decode base64 failed"},
267- {TPM_R_DECRYPT_SRK_PW_FAILED, "decrypt srk password failed"},
268+ {TPM_R_DECRYPT_PW_FAILED, "decrypt password failed"},
269 {0, NULL}
270 };
271
272--
2732.9.3
274
diff --git a/meta-tpm/recipes-tpm/openssl-tpm-engine/openssl-tpm-engine_git.bb b/meta-tpm/recipes-tpm/openssl-tpm-engine/openssl-tpm-engine_git.bb
index 853590d..54766a5 100644
--- a/meta-tpm/recipes-tpm/openssl-tpm-engine/openssl-tpm-engine_git.bb
+++ b/meta-tpm/recipes-tpm/openssl-tpm-engine/openssl-tpm-engine_git.bb
@@ -16,6 +16,7 @@ SRC_URI = "\
16 file://0003-Fix-not-building-libtpm.la.patch \ 16 file://0003-Fix-not-building-libtpm.la.patch \
17 file://0003-tpm-openssl-tpm-engine-parse-an-encrypted-tpm-SRK-pa.patch \ 17 file://0003-tpm-openssl-tpm-engine-parse-an-encrypted-tpm-SRK-pa.patch \
18 file://0004-tpm-openssl-tpm-engine-change-variable-c-type-from-c.patch \ 18 file://0004-tpm-openssl-tpm-engine-change-variable-c-type-from-c.patch \
19 file://0005-tpm-openssl-tpm-engine-parse-an-encrypted-TPM-key-pa.patch \
19" 20"
20SRCREV = "bbc2b1af809f20686e0d3553a62f0175742c0d60" 21SRCREV = "bbc2b1af809f20686e0d3553a62f0175742c0d60"
21 22
@@ -29,19 +30,22 @@ inherit autotools-brokensep
29# srk_dec_pw = "incendia" 30# srk_dec_pw = "incendia"
30# srk_dec_pw = "\x69\x6e\x63\x65\x6e\x64\x69\x61" 31# srk_dec_pw = "\x69\x6e\x63\x65\x6e\x64\x69\x61"
31# srk_dec_pw = "\x1""nc""\x3""nd""\x1""a" 32# srk_dec_pw = "\x1""nc""\x3""nd""\x1""a"
32# 33
34# The definitions below are used to decrypt the passwords of both srk and loaded key.
35dec_pw ?= "\\"\\\x1\\"\\"nc\\"\\"\\\x3\\"\\"nd\\"\\"\\\x1\\"\\"a\\""
36dec_salt ?= "\\"r\\"\\"\\\x00\\\x00\\"\\"t\\""
37CFLAGS_append += "-DDEC_PW=${dec_pw} -DDEC_SALT=${dec_salt}"
33# Due to the limit of escape character, the hybrid must be written in 38# Due to the limit of escape character, the hybrid must be written in
34# above style. The actual values defined below in C code style are: 39# above style. The actual values defined below in C code style are:
35# srk_dec_pw[] = { 0x01, 'n', 'c', 0x03, 'n', 'd', 0x01, 'a' }; 40# dec_pw[] = {0x01, 'n', 'c', 0x03, 'n', 'd', 0x01, 'a'};
36# srk_dec_salt[] = { 'r', 0x00, 0x00, 't' }; 41# dec_salt[] = {'r', 0x00, 0x00, 't'};
37srk_dec_pw ?= "\\"\\\x1\\"\\"nc\\"\\"\\\x3\\"\\"nd\\"\\"\\\x1\\"\\"a\\""
38srk_dec_salt ?= "\\"r\\"\\"\\\x00\\\x00\\"\\"t\\""
39
40CFLAGS_append += "-DSRK_DEC_PW=${srk_dec_pw} -DSRK_DEC_SALT=${srk_dec_salt}"
41 42
42# Uncomment below line if using the plain srk password for development 43# Uncomment below line if using the plain srk password for development
43#CFLAGS_append += "-DTPM_SRK_PLAIN_PW" 44#CFLAGS_append += "-DTPM_SRK_PLAIN_PW"
44 45
46# Uncomment below line if using the plain tpm key password for development
47#CFLAGS_append += "-DTPM_KEY_PLAIN_PW"
48
45do_configure_prepend() { 49do_configure_prepend() {
46 cd "${S}" 50 cd "${S}"
47 cp LICENSE COPYING 51 cp LICENSE COPYING