2
* Userspace side of communications with eCryptfs kernel module.
4
* Copyright (C) 2004-2006 International Business Machines Corp.
5
* Author(s): Trevor S. Highland <trevor.highland@gmail.com>
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License as
9
* published by the Free Software Foundation; either version 2 of the
10
* License, or (at your option) any later version.
12
* This program is distributed in the hope that it will be useful, but
13
* WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
33
#include "../include/ecryptfs.h"
35
#define ECRYPTFS_PACKET_STATUS_GOOD 0
36
#define ECRYPTFS_PACKET_STATUS_BAD -1
40
* @encrypted_key: This function will allocate this memory and encrypt
42
* @encrypted_key_size: The size of the encrypted key; note that the
43
* actual amount of memory allocated by this
44
* function may be more than this
46
* @auth_tok: The authentication token structure in the user session
47
* keyring; this contains the key module state blob
49
* @decrypted_key_size:
53
* Called from parse_packet()
56
key_mod_encrypt(char **encrypted_key, size_t *encrypted_key_size,
57
struct ecryptfs_ctx *ctx, struct ecryptfs_auth_tok *auth_tok,
58
char *decrypted_key, size_t decrypted_key_size)
60
struct ecryptfs_key_mod *key_mod;
63
if (ecryptfs_find_key_mod(&key_mod, ctx,
64
auth_tok->token.private_key.key_mod_alias)) {
66
syslog(LOG_ERR, "Failed to locate desired key module\n");
69
/* TODO: Include support for a hint rather than just a blob */
70
if ((rc = key_mod->ops->encrypt(NULL, encrypted_key_size, decrypted_key,
72
auth_tok->token.private_key.data,
73
ECRYPTFS_BLOB_TYPE_BLOB))) {
74
syslog(LOG_ERR, "Error attempting to get encrypted key size "
75
"from key module; rc = [%d]\n", rc);
78
if ((*encrypted_key_size) == 0) {
80
syslog(LOG_ERR, "Encrypted key size reported by key module "
81
"encrypt function is 0\n");
84
/* The first call just told us how much memory to
85
* allocate. The actual key size may be less, so we don't
86
* worry about ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES until the
88
if (((*encrypted_key) = malloc(*encrypted_key_size)) == NULL) {
90
syslog(LOG_ERR, "Failed to allocate memory: [%s]\n",
94
if ((rc = key_mod->ops->encrypt((*encrypted_key), encrypted_key_size,
95
decrypted_key, decrypted_key_size,
96
auth_tok->token.private_key.data,
97
ECRYPTFS_BLOB_TYPE_BLOB))) {
98
syslog(LOG_ERR, "Failed to encrypt key; rc = [%d]\n", rc);
101
if ((*encrypted_key_size) > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) {
103
syslog(LOG_ERR, "Encrypted key size reported by key module "
104
"encrypt function is [%d]; max is [%d]\n",
105
(*encrypted_key_size), ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES);
106
free(*encrypted_key);
107
(*encrypted_key_size) = 0;
115
key_mod_decrypt(char **decrypted_key, size_t *decrypted_key_size,
116
struct ecryptfs_ctx *ctx, struct ecryptfs_auth_tok *auth_tok,
117
char *encrypted_key, size_t encrypted_key_size)
119
struct ecryptfs_key_mod *key_mod;
122
if (ecryptfs_find_key_mod(&key_mod, ctx,
123
auth_tok->token.private_key.key_mod_alias)) {
125
syslog(LOG_ERR, "Failed to locate desired key module\n");
128
if ((rc = key_mod->ops->decrypt(NULL, decrypted_key_size,
129
encrypted_key, encrypted_key_size,
130
auth_tok->token.private_key.data,
131
ECRYPTFS_BLOB_TYPE_BLOB))) {
132
syslog(LOG_ERR, "Failed to get size for decrypted key\n");
135
if ((*decrypted_key_size) == 0) {
137
syslog(LOG_ERR, "Decrypted key size reported by key module "
138
"decrypt function is 0\n");
141
/* The first call just told us how much memory to
142
* allocate. The actual key size may be less, so we don't
143
* worry about ECRYPTFS_MAX_KEY_BYTES until the second
145
if (((*decrypted_key) = malloc(*decrypted_key_size)) == NULL) {
147
syslog(LOG_ERR, "Failed to allocate memory\n");
150
if ((rc = key_mod->ops->decrypt(*decrypted_key, decrypted_key_size,
151
encrypted_key, encrypted_key_size,
152
auth_tok->token.private_key.data,
153
ECRYPTFS_BLOB_TYPE_BLOB))) {
154
syslog(LOG_ERR, "Failed to decrypt key\n");
157
if ((*decrypted_key_size) > ECRYPTFS_MAX_KEY_BYTES) {
159
syslog(LOG_ERR, "Decrypted key size reported by key module "
160
"decrypt function is [%d]; max is [%d]\n",
161
(*decrypted_key_size), ECRYPTFS_MAX_KEY_BYTES);
162
free(*decrypted_key);
163
(*decrypted_key_size) = 0;
170
static int write_failure_packet(size_t tag,
171
struct ecryptfs_message **reply)
177
*reply = malloc(sizeof(struct ecryptfs_message) + 2);
180
syslog(LOG_ERR, "Failed to allocate memory: %s\n",
184
data = (*reply)->data;
186
data[i++] = ECRYPTFS_PACKET_STATUS_BAD;
187
(*reply)->data_len = i;
192
static int write_tag_65_packet(unsigned char *key, size_t key_size,
193
struct ecryptfs_message **reply)
201
data_len = key_size + 4;
202
*reply = malloc(sizeof(struct ecryptfs_message) + data_len);
205
syslog(LOG_ERR, "Failed to allocate memory: %s\n",
209
data = (*reply)->data;
210
data[i++] = ECRYPTFS_TAG_65_PACKET;
211
data[i++] = ECRYPTFS_PACKET_STATUS_GOOD;
212
rc = ecryptfs_write_packet_length(&data[i], key_size, &length_size);
214
syslog(LOG_ERR, "Invalid packet format\n");
218
memcpy(&data[i], key, key_size);
220
(*reply)->data_len = i;
226
write_tag_67_packet(char *key, size_t key_size,
227
struct ecryptfs_message **reply)
235
data_len = key_size + 4;
236
*reply = malloc(sizeof(struct ecryptfs_message) + data_len);
239
syslog(LOG_ERR, "Failed to allocate memory: %s\n",
243
data = (*reply)->data;
244
data[i++] = ECRYPTFS_TAG_67_PACKET;
245
data[i++] = ECRYPTFS_PACKET_STATUS_GOOD;
246
rc = ecryptfs_write_packet_length(&data[i], key_size, &length_size);
248
syslog(LOG_ERR, "Invalid packet format\n");
252
memcpy(&data[i], key, key_size);
254
(*reply)->data_len = data_len;
259
int parse_packet(struct ecryptfs_ctx *ctx,
260
struct ecryptfs_message *emsg,
261
struct ecryptfs_message **reply)
263
struct ecryptfs_auth_tok *auth_tok = NULL;
269
unsigned char *signature;
270
unsigned char packet_type;
272
char *key_out = NULL;
273
key_serial_t key_sub;
276
packet_type = emsg->data[i++];
277
if ((rc = ecryptfs_parse_packet_length(&emsg->data[i], &data_size,
279
syslog(LOG_ERR, "Invalid packet format\n");
283
signature = malloc(data_size + 1);
286
syslog(LOG_ERR, "Failed to allocate memory: %s\n",
290
memcpy(signature, &emsg->data[i], data_size);
291
signature[data_size] = '\0';
293
rc = ecryptfs_parse_packet_length(&emsg->data[i], &key_size,
296
syslog(LOG_ERR, "Invalid packet format\n");
300
if ((key = malloc(key_size)) == NULL) {
302
syslog(LOG_ERR, "Failed to allocate memory\n");
305
memcpy(key, &emsg->data[i], key_size);
307
key_sub = request_key("user", signature, NULL, KEY_SPEC_USER_KEYRING);
309
syslog(LOG_ERR, "Could not find key with signature: "
310
"[%s]\n", signature);
314
rc = keyctl_read_alloc(key_sub, (void **)(&auth_tok));
315
switch (packet_type) {
316
case ECRYPTFS_TAG_64_PACKET:
317
if ((rc = key_mod_decrypt(&key_out, &key_out_size, ctx,
318
auth_tok, key, key_size))) {
319
syslog(LOG_ERR, "Failed to decrypt key; rc = [%d]\n",
321
rc = write_failure_packet(ECRYPTFS_TAG_65_PACKET,
325
if ((rc = write_tag_65_packet(key_out, key_out_size, reply))) {
326
syslog(LOG_ERR, "Failed to write decrypted "
327
"key via tag 65 packet\n");
331
case ECRYPTFS_TAG_66_PACKET:
332
rc = key_mod_encrypt(&key_out, &key_out_size, ctx, auth_tok,
335
syslog(LOG_ERR, "Failed to encrypt public "
339
rc = write_tag_67_packet(key_out, key_out_size, reply);
341
syslog(LOG_ERR, "Failed to write encrypted "
342
"key to tag 67 packet\n");
347
syslog(LOG_ERR, "Unrecognized packet type: [%d]\n",
355
memset(auth_tok, 0, (sizeof(struct ecryptfs_auth_tok)
356
+ auth_tok->token.private_key.data_len));
360
if(packet_type == ECRYPTFS_TAG_66_PACKET)
361
rc = write_failure_packet(ECRYPTFS_TAG_67_PACKET, reply);
363
rc = write_failure_packet(ECRYPTFS_TAG_65_PACKET, reply);
368
memset(auth_tok, 0, (sizeof(struct ecryptfs_auth_tok)
369
+ auth_tok->token.private_key.data_len));