2
* Copyright (C) 2006 International Business Machines
3
* Author(s): Michael C. Thompson <mcthomps@us.ibm.com>
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License as
7
* published by the Free Software Foundation; either version 2 of the
8
* License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful, but
11
* WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
32
#include <arpa/inet.h>
34
#include <sys/types.h>
37
#include "../include/ecryptfs.h"
40
#warning ENOKEY is not defined in your errno.h; setting it to 126
45
* This is the common functionality used to put a password generated key into
46
* the keyring, shared by both non-interactive and interactive signature
49
* Returns 0 on add, 1 on pre-existed, negative on failure.
51
int ecryptfs_add_passphrase_key_to_keyring(char *auth_tok_sig, char *passphrase,
55
char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES];
56
struct ecryptfs_auth_tok *auth_tok = NULL;
58
if ((rc = generate_passphrase_sig(auth_tok_sig, passphrase, salt,
59
session_key_encryption_key))) {
60
syslog(LOG_ERR, "Error generating passphrase signature; "
62
rc = (rc < 0) ? rc : rc * -1;
65
rc = (int)keyctl_search(KEY_SPEC_USER_KEYRING, "user", auth_tok_sig, 0);
66
if (rc != -1) { /* we already have this key in keyring; we're done */
68
syslog(LOG_WARNING, "Passphrase key already in keyring\n", rc);
70
} else if ((rc == -1) && (errno != ENOKEY)) {
73
syslog(LOG_ERR, "keyctl_search failed: %s errno=[%d]\n",
74
strerror(errnum), errnum);
75
rc = (errnum < 0) ? errnum : errnum * -1;
78
auth_tok = malloc(sizeof(struct ecryptfs_auth_tok));
80
syslog(LOG_ERR, "Unable to allocate memory for auth_tok\n");
84
if ((rc = generate_payload(auth_tok, auth_tok_sig, salt,
85
session_key_encryption_key))) {
86
syslog(LOG_ERR, "Error generating payload for auth tok key; "
88
rc = (rc < 0) ? rc : rc * -1;
91
rc = add_key("user", auth_tok_sig, (void *)auth_tok,
92
sizeof(struct ecryptfs_auth_tok), KEY_SPEC_USER_KEYRING);
96
syslog(LOG_ERR, "Error adding key with sig [%s]; rc = [%d] "
97
"\%s\"\n", auth_tok_sig, rc, strerror(errnum));
98
rc = (errnum < 0) ? errnum : errnum * -1;
103
memset(auth_tok, 0, sizeof(auth_tok));
109
int ecryptfs_wrap_passphrase(char *filename, char *wrapping_passphrase,
110
char *wrapping_salt, char *decrypted_passphrase)
112
char wrapping_auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX + 1];
113
char wrapping_key[ECRYPTFS_MAX_KEY_BYTES];
114
char padded_decrypted_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES + 1];
115
char encrypted_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES + 1];
116
int encrypted_passphrase_pos = 0;
117
int decrypted_passphrase_pos = 0;
118
gcry_cipher_hd_t gcry_handle;
119
gcry_error_t gcry_err;
120
int encrypted_passphrase_bytes;
121
int decrypted_passphrase_bytes;
126
decrypted_passphrase_bytes = strlen(decrypted_passphrase);
127
if (decrypted_passphrase_bytes > ECRYPTFS_MAX_PASSPHRASE_BYTES) {
128
syslog(LOG_ERR, "Decrypted passphrase is [%d] bytes long; "
129
"[%d] is the max\n", decrypted_passphrase_bytes,
130
ECRYPTFS_MAX_PASSPHRASE_BYTES);
134
if ((rc = generate_passphrase_sig(wrapping_auth_tok_sig,
135
wrapping_passphrase, wrapping_salt,
137
syslog(LOG_ERR, "Error generating passphrase signature; "
139
rc = (rc < 0) ? rc : rc * -1;
142
memset(padded_decrypted_passphrase, 0,
143
(ECRYPTFS_MAX_PASSPHRASE_BYTES + 1));
144
memcpy(padded_decrypted_passphrase, decrypted_passphrase,
145
decrypted_passphrase_bytes);
146
if ((decrypted_passphrase_bytes % ECRYPTFS_AES_BLOCK_SIZE) != 0)
147
decrypted_passphrase_bytes += (ECRYPTFS_AES_BLOCK_SIZE
148
- (decrypted_passphrase_bytes
149
% ECRYPTFS_AES_BLOCK_SIZE));
150
encrypted_passphrase_bytes = decrypted_passphrase_bytes;
151
if ((gcry_err = gcry_cipher_open(&gcry_handle, GCRY_CIPHER_AES,
152
GCRY_CIPHER_MODE_ECB, 0))) {
153
syslog(LOG_ERR, "Error attempting to initialize AES cipher; "
154
"gcry_error_t = [%d]\n", gcry_err);
158
if ((gcry_err = gcry_cipher_setkey(gcry_handle, wrapping_key,
159
ECRYPTFS_AES_KEY_BYTES))) {
160
syslog(LOG_ERR, "Error attempting to set AES key; "
161
"gcry_error_t = [%d]\n", gcry_err);
163
gcry_cipher_close(gcry_handle);
166
while (decrypted_passphrase_bytes > 0) {
167
if ((gcry_err = gcry_cipher_encrypt(
169
&encrypted_passphrase[encrypted_passphrase_pos],
170
ECRYPTFS_AES_BLOCK_SIZE,
171
&decrypted_passphrase[decrypted_passphrase_pos],
172
ECRYPTFS_AES_BLOCK_SIZE))) {
173
syslog(LOG_ERR, "Error attempting to encrypt block; "
174
"gcry_error = [%d]\n", gcry_err);
176
gcry_cipher_close(gcry_handle);
179
encrypted_passphrase_pos += ECRYPTFS_AES_BLOCK_SIZE;
180
decrypted_passphrase_pos += ECRYPTFS_AES_BLOCK_SIZE;
181
decrypted_passphrase_bytes -= ECRYPTFS_AES_BLOCK_SIZE;
183
gcry_cipher_close(gcry_handle);
185
if ((fd = open(filename, (O_WRONLY | O_CREAT | O_EXCL),
186
(S_IRUSR | S_IWUSR))) == -1) {
187
syslog(LOG_ERR, "Error attempting to open [%s] for writing\n",
192
if ((size = write(fd, wrapping_auth_tok_sig,
193
ECRYPTFS_SIG_SIZE_HEX)) <= 0) {
194
syslog(LOG_ERR, "Error attempting to write encrypted "
195
"passphrase ([%d] bytes) to file [%s]; size = [%d]\n",
196
encrypted_passphrase_bytes, filename, size);
201
if ((size = write(fd, encrypted_passphrase,
202
encrypted_passphrase_bytes)) <= 0) {
203
syslog(LOG_ERR, "Error attempting to write encrypted "
204
"passphrase ([%d] bytes) to file [%s]; size = [%d]\n",
205
encrypted_passphrase_bytes, filename, size);
217
* decryptfs_passphrase must be able to hold
218
* ECRYPTFS_MAX_PASSPHRASE_BYTES + 1 bytes
220
int ecryptfs_unwrap_passphrase(char *decrypted_passphrase, char *filename,
221
char *wrapping_passphrase, char *wrapping_salt)
223
char wrapping_auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX + 1];
224
char wrapping_auth_tok_sig_from_file[ECRYPTFS_SIG_SIZE_HEX + 1];
225
char wrapping_key[ECRYPTFS_MAX_KEY_BYTES];
226
char encrypted_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES + 1];
227
int encrypted_passphrase_pos = 0;
228
int decrypted_passphrase_pos = 0;
229
gcry_cipher_hd_t gcry_handle;
230
gcry_error_t gcry_err;
231
int encrypted_passphrase_bytes;
236
if ((rc = generate_passphrase_sig(wrapping_auth_tok_sig,
237
wrapping_passphrase, wrapping_salt,
239
syslog(LOG_ERR, "Error generating passphrase signature; "
241
rc = (rc < 0) ? rc : rc * -1;
244
if ((fd = open(filename, O_RDONLY)) == -1) {
245
syslog(LOG_ERR, "Error attempting to open [%s] for reading\n",
250
if ((size = read(fd, wrapping_auth_tok_sig_from_file,
251
ECRYPTFS_SIG_SIZE_HEX)) <= 0) {
252
syslog(LOG_ERR, "Error attempting to read encrypted "
253
"passphrase from file [%s]; size = [%d]\n",
259
if ((size = read(fd, encrypted_passphrase,
260
ECRYPTFS_MAX_PASSPHRASE_BYTES)) <= 0) {
261
syslog(LOG_ERR, "Error attempting to read encrypted "
262
"passphrase from file [%s]; size = [%d]\n",
269
if (memcmp(wrapping_auth_tok_sig_from_file, wrapping_auth_tok_sig,
270
ECRYPTFS_SIG_SIZE_HEX) != 0) {
271
syslog(LOG_ERR, "Incorrect wrapping key for file [%s]\n",
276
encrypted_passphrase_bytes = size;
277
if ((gcry_err = gcry_cipher_open(&gcry_handle, GCRY_CIPHER_AES,
278
GCRY_CIPHER_MODE_ECB, 0))) {
279
syslog(LOG_ERR, "Error attempting to initialize AES cipher; "
280
"gcry_error_t = [%d]\n", gcry_err);
284
if ((gcry_err = gcry_cipher_setkey(gcry_handle, wrapping_key,
285
ECRYPTFS_AES_KEY_BYTES))) {
286
syslog(LOG_ERR, "Error attempting to set AES key; "
287
"gcry_error_t = [%d]\n", gcry_err);
289
gcry_cipher_close(gcry_handle);
292
memset(decrypted_passphrase, 0, ECRYPTFS_MAX_PASSPHRASE_BYTES + 1);
293
while (encrypted_passphrase_bytes > 0) {
294
if ((gcry_err = gcry_cipher_decrypt(
296
&decrypted_passphrase[encrypted_passphrase_pos],
297
ECRYPTFS_AES_BLOCK_SIZE,
298
&encrypted_passphrase[decrypted_passphrase_pos],
299
ECRYPTFS_AES_BLOCK_SIZE))) {
300
syslog(LOG_ERR, "Error attempting to decrypt block; "
301
"gcry_error = [%d]\n", gcry_err);
303
gcry_cipher_close(gcry_handle);
306
encrypted_passphrase_pos += ECRYPTFS_AES_BLOCK_SIZE;
307
decrypted_passphrase_pos += ECRYPTFS_AES_BLOCK_SIZE;
308
encrypted_passphrase_bytes -= ECRYPTFS_AES_BLOCK_SIZE;
315
* ecryptfs_insert_wrapped_passphrase_into_keyring()
317
* Inserts two auth_tok objects into the user session keyring: a
318
* wrapping passphrase auth_tok and the unwrapped passphrase auth_tok.
320
* Returns the signature of the wrapped passphrase that is inserted
321
* into the user session keyring.
323
int ecryptfs_insert_wrapped_passphrase_into_keyring(
324
char *auth_tok_sig, char *filename, char *wrapping_passphrase,
327
char decrypted_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES + 1] ;
330
if ((rc = ecryptfs_unwrap_passphrase(decrypted_passphrase, filename,
331
wrapping_passphrase, salt))) {
332
syslog(LOG_ERR, "Error attempting to unwrap passphrase from "
333
"file [%s]; rc = [%d]\n", filename, rc);
337
if ((rc = ecryptfs_add_passphrase_key_to_keyring(auth_tok_sig,
338
decrypted_passphrase,
340
syslog(LOG_ERR, "Error attempting to add passphrase key to "
341
"user session keyring; rc = [%d]\n", rc);
349
* ecryptfs_add_key_module_key_to_keyring
350
* @auth_tok_sig: (ECRYPTFS_SIG_SIZE_HEX + 1) bytes of allocated
351
* memory into which this function will write the
352
* expanded-hex key signature for the given key
354
* @key_mod: Key module handle
356
* Inserts a key module key blob into the keyring, using the
357
* auth_tok_sig as the key signature.
359
* Returns =0 on successful addition, =1 if the key is already in the
360
* keyring, and <0 on failure.
363
ecryptfs_add_key_module_key_to_keyring(char *auth_tok_sig,
364
struct ecryptfs_key_mod *key_mod)
367
struct ecryptfs_auth_tok *auth_tok;
370
if (key_mod->blob == NULL) {
371
if ((rc = (key_mod->ops->get_blob)(NULL, &blob_size,
373
key_mod->num_param_vals))) {
374
syslog(LOG_ERR, "Error attempting to get blob from "
375
"key module; rc = [%d]\n", rc);
379
blob_size = key_mod->blob_size;
381
if ((auth_tok = malloc(sizeof(struct ecryptfs_auth_tok) + blob_size))
386
if ((rc = ecryptfs_generate_key_payload(auth_tok, key_mod, auth_tok_sig,
388
syslog(LOG_ERR, "Error initializing key from module; "
392
rc = (int)keyctl_search(KEY_SPEC_USER_KEYRING, "user", auth_tok_sig, 0);
393
if (rc != -1) { /* we already have this key in keyring; we're done */
397
rc = add_key("user", auth_tok_sig, (void *)auth_tok,
398
(sizeof(struct ecryptfs_auth_tok) + blob_size),
399
KEY_SPEC_USER_KEYRING);
401
syslog(LOG_ERR, "Error adding key with sig [%s]; rc ="
402
" [%d]\n", auth_tok_sig, rc);
405
memset(auth_tok, 0, (sizeof(struct ecryptfs_auth_tok) + blob_size));
410
int ecryptfs_read_salt_hex_from_rc(char *salt_hex)
412
struct ecryptfs_name_val_pair nvp_list_head;
413
struct ecryptfs_name_val_pair *nvp;
416
memset(&nvp_list_head, 0, sizeof(struct ecryptfs_name_val_pair));
417
rc = ecryptfs_parse_rc_file(&nvp_list_head);
419
syslog(LOG_WARNING, "Error attempting to parse .ecryptfsrc "
420
"file; rc = [%d]", rc);
423
nvp = &nvp_list_head;
425
if (strcmp(nvp->name, "salt") == 0) {
430
valsize = strlen(nvp->value);
431
if (valsize != ECRYPTFS_SALT_SIZE_HEX);
433
memcpy(salt_hex, nvp->value, ECRYPTFS_SALT_SIZE_HEX);
441
free_name_val_pairs(nvp_list_head.next);
446
int ecryptfs_check_sig(char *auth_tok_sig, char *sig_cache_filename,
450
char tmp[ECRYPTFS_SIG_SIZE_HEX + 1];
454
(*flags) &= ~ECRYPTFS_SIG_FLAG_NOENT;
455
fd = open(sig_cache_filename, O_RDONLY);
457
(*flags) |= ECRYPTFS_SIG_FLAG_NOENT;
460
while ((size = read(fd, tmp, (ECRYPTFS_SIG_SIZE_HEX + 1)))
461
== (ECRYPTFS_SIG_SIZE_HEX + 1)) {
462
if (memcmp(auth_tok_sig, tmp, ECRYPTFS_SIG_SIZE_HEX)
469
(*flags) |= ECRYPTFS_SIG_FLAG_NOENT;
474
int ecryptfs_append_sig(char *auth_tok_sig, char *sig_cache_filename)
478
char tmp[ECRYPTFS_SIG_SIZE_HEX + 1];
481
fd = open(sig_cache_filename, (O_WRONLY | O_CREAT),
482
(S_IRUSR | S_IWUSR));
484
syslog(LOG_ERR, "Open resulted in [%d]; [%s]\n", errno,
489
lseek(fd, 0, SEEK_END);
490
memcpy(tmp, auth_tok_sig, ECRYPTFS_SIG_SIZE_HEX);
491
tmp[ECRYPTFS_SIG_SIZE_HEX] = '\n';
492
if ((size = write(fd, tmp, (ECRYPTFS_SIG_SIZE_HEX + 1))) !=
493
(ECRYPTFS_SIG_SIZE_HEX + 1)) {
494
syslog(LOG_ERR, "Write of sig resulted in [%d]; errno = [%d]; "
495
"[%s]\n", size, errno, strerror(errno));
505
int ecryptfs_validate_keyring(void)
510
if ((rc_long = keyctl(KEYCTL_LINK, KEY_SPEC_USER_KEYRING,
511
KEY_SPEC_SESSION_KEYRING))) {
512
syslog(LOG_ERR, "Error attempting to link the user session "
513
"keyring into the session keyring\n");