aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Halcrow <mhalcrow@us.ibm.com>2009-01-06 17:42:01 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-06 18:59:22 -0500
commit87c94c4df0149786ad91d8a03c738a03369ee9c8 (patch)
tree6b7ee0b3c3e15d94fdeccb59e8bfab6c9d2a4498
parentaddd65ad8d19a7d7982130b16f957d5d01d3f8df (diff)
eCryptfs: Filename Encryption: mount option
Enable mount-wide filename encryption by providing the Filename Encryption Key (FNEK) signature as a mount option. Note that the ecryptfs-utils userspace package versions 61 or later support this option. When mounting with ecryptfs-utils version 61 or later, the mount helper will detect the availability of the passphrase-based filename encryption in the kernel (via the eCryptfs sysfs handle) and query the user interactively as to whether or not he wants to enable the feature for the mount. If the user enables filename encryption, the mount helper will then prompt for the FNEK signature that the user wishes to use, suggesting by default the signature for the mount passphrase that the user has already entered for encrypting the file contents. When not using the mount helper, the user can specify the signature for the passphrase key with the ecryptfs_fnek_sig= mount option. This key must be available in the user's keyring. The mount helper usually takes care of this step. If, however, the user is not mounting with the mount helper, then he will need to enter the passphrase key into his keyring with some other utility prior to mounting, such as ecryptfs-manager. Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com> Cc: Dustin Kirkland <dustin.kirkland@gmail.com> Cc: Eric Sandeen <sandeen@redhat.com> Cc: Tyler Hicks <tchicks@us.ibm.com> Cc: David Kleikamp <shaggy@us.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/ecryptfs/main.c126
1 files changed, 99 insertions, 27 deletions
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index fd630713c5c7..789cf2e1be1e 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -206,7 +206,9 @@ enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig,
206 ecryptfs_opt_cipher, ecryptfs_opt_ecryptfs_cipher, 206 ecryptfs_opt_cipher, ecryptfs_opt_ecryptfs_cipher,
207 ecryptfs_opt_ecryptfs_key_bytes, 207 ecryptfs_opt_ecryptfs_key_bytes,
208 ecryptfs_opt_passthrough, ecryptfs_opt_xattr_metadata, 208 ecryptfs_opt_passthrough, ecryptfs_opt_xattr_metadata,
209 ecryptfs_opt_encrypted_view, ecryptfs_opt_err }; 209 ecryptfs_opt_encrypted_view, ecryptfs_opt_fnek_sig,
210 ecryptfs_opt_fn_cipher, ecryptfs_opt_fn_cipher_key_bytes,
211 ecryptfs_opt_err };
210 212
211static const match_table_t tokens = { 213static const match_table_t tokens = {
212 {ecryptfs_opt_sig, "sig=%s"}, 214 {ecryptfs_opt_sig, "sig=%s"},
@@ -217,6 +219,9 @@ static const match_table_t tokens = {
217 {ecryptfs_opt_passthrough, "ecryptfs_passthrough"}, 219 {ecryptfs_opt_passthrough, "ecryptfs_passthrough"},
218 {ecryptfs_opt_xattr_metadata, "ecryptfs_xattr_metadata"}, 220 {ecryptfs_opt_xattr_metadata, "ecryptfs_xattr_metadata"},
219 {ecryptfs_opt_encrypted_view, "ecryptfs_encrypted_view"}, 221 {ecryptfs_opt_encrypted_view, "ecryptfs_encrypted_view"},
222 {ecryptfs_opt_fnek_sig, "ecryptfs_fnek_sig=%s"},
223 {ecryptfs_opt_fn_cipher, "ecryptfs_fn_cipher=%s"},
224 {ecryptfs_opt_fn_cipher_key_bytes, "ecryptfs_fn_key_bytes=%u"},
220 {ecryptfs_opt_err, NULL} 225 {ecryptfs_opt_err, NULL}
221}; 226};
222 227
@@ -281,8 +286,11 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
281 int rc = 0; 286 int rc = 0;
282 int sig_set = 0; 287 int sig_set = 0;
283 int cipher_name_set = 0; 288 int cipher_name_set = 0;
289 int fn_cipher_name_set = 0;
284 int cipher_key_bytes; 290 int cipher_key_bytes;
285 int cipher_key_bytes_set = 0; 291 int cipher_key_bytes_set = 0;
292 int fn_cipher_key_bytes;
293 int fn_cipher_key_bytes_set = 0;
286 struct ecryptfs_mount_crypt_stat *mount_crypt_stat = 294 struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
287 &ecryptfs_superblock_to_private(sb)->mount_crypt_stat; 295 &ecryptfs_superblock_to_private(sb)->mount_crypt_stat;
288 substring_t args[MAX_OPT_ARGS]; 296 substring_t args[MAX_OPT_ARGS];
@@ -290,7 +298,12 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
290 char *sig_src; 298 char *sig_src;
291 char *cipher_name_dst; 299 char *cipher_name_dst;
292 char *cipher_name_src; 300 char *cipher_name_src;
301 char *fn_cipher_name_dst;
302 char *fn_cipher_name_src;
303 char *fnek_dst;
304 char *fnek_src;
293 char *cipher_key_bytes_src; 305 char *cipher_key_bytes_src;
306 char *fn_cipher_key_bytes_src;
294 307
295 if (!options) { 308 if (!options) {
296 rc = -EINVAL; 309 rc = -EINVAL;
@@ -322,10 +335,7 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
322 global_default_cipher_name; 335 global_default_cipher_name;
323 strncpy(cipher_name_dst, cipher_name_src, 336 strncpy(cipher_name_dst, cipher_name_src,
324 ECRYPTFS_MAX_CIPHER_NAME_SIZE); 337 ECRYPTFS_MAX_CIPHER_NAME_SIZE);
325 ecryptfs_printk(KERN_DEBUG, 338 cipher_name_dst[ECRYPTFS_MAX_CIPHER_NAME_SIZE] = '\0';
326 "The mount_crypt_stat "
327 "global_default_cipher_name set to: "
328 "[%s]\n", cipher_name_dst);
329 cipher_name_set = 1; 339 cipher_name_set = 1;
330 break; 340 break;
331 case ecryptfs_opt_ecryptfs_key_bytes: 341 case ecryptfs_opt_ecryptfs_key_bytes:
@@ -335,11 +345,6 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
335 &cipher_key_bytes_src, 0); 345 &cipher_key_bytes_src, 0);
336 mount_crypt_stat->global_default_cipher_key_size = 346 mount_crypt_stat->global_default_cipher_key_size =
337 cipher_key_bytes; 347 cipher_key_bytes;
338 ecryptfs_printk(KERN_DEBUG,
339 "The mount_crypt_stat "
340 "global_default_cipher_key_size "
341 "set to: [%d]\n", mount_crypt_stat->
342 global_default_cipher_key_size);
343 cipher_key_bytes_set = 1; 348 cipher_key_bytes_set = 1;
344 break; 349 break;
345 case ecryptfs_opt_passthrough: 350 case ecryptfs_opt_passthrough:
@@ -356,11 +361,51 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
356 mount_crypt_stat->flags |= 361 mount_crypt_stat->flags |=
357 ECRYPTFS_ENCRYPTED_VIEW_ENABLED; 362 ECRYPTFS_ENCRYPTED_VIEW_ENABLED;
358 break; 363 break;
364 case ecryptfs_opt_fnek_sig:
365 fnek_src = args[0].from;
366 fnek_dst =
367 mount_crypt_stat->global_default_fnek_sig;
368 strncpy(fnek_dst, fnek_src, ECRYPTFS_SIG_SIZE_HEX);
369 mount_crypt_stat->global_default_fnek_sig[
370 ECRYPTFS_SIG_SIZE_HEX] = '\0';
371 rc = ecryptfs_add_global_auth_tok(
372 mount_crypt_stat,
373 mount_crypt_stat->global_default_fnek_sig);
374 if (rc) {
375 printk(KERN_ERR "Error attempting to register "
376 "global fnek sig [%s]; rc = [%d]\n",
377 mount_crypt_stat->global_default_fnek_sig,
378 rc);
379 goto out;
380 }
381 mount_crypt_stat->flags |=
382 (ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES
383 | ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK);
384 break;
385 case ecryptfs_opt_fn_cipher:
386 fn_cipher_name_src = args[0].from;
387 fn_cipher_name_dst =
388 mount_crypt_stat->global_default_fn_cipher_name;
389 strncpy(fn_cipher_name_dst, fn_cipher_name_src,
390 ECRYPTFS_MAX_CIPHER_NAME_SIZE);
391 mount_crypt_stat->global_default_fn_cipher_name[
392 ECRYPTFS_MAX_CIPHER_NAME_SIZE] = '\0';
393 fn_cipher_name_set = 1;
394 break;
395 case ecryptfs_opt_fn_cipher_key_bytes:
396 fn_cipher_key_bytes_src = args[0].from;
397 fn_cipher_key_bytes =
398 (int)simple_strtol(fn_cipher_key_bytes_src,
399 &fn_cipher_key_bytes_src, 0);
400 mount_crypt_stat->global_default_fn_cipher_key_bytes =
401 fn_cipher_key_bytes;
402 fn_cipher_key_bytes_set = 1;
403 break;
359 case ecryptfs_opt_err: 404 case ecryptfs_opt_err:
360 default: 405 default:
361 ecryptfs_printk(KERN_WARNING, 406 printk(KERN_WARNING
362 "eCryptfs: unrecognized option '%s'\n", 407 "%s: eCryptfs: unrecognized option [%s]\n",
363 p); 408 __func__, p);
364 } 409 }
365 } 410 }
366 if (!sig_set) { 411 if (!sig_set) {
@@ -374,33 +419,60 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
374 int cipher_name_len = strlen(ECRYPTFS_DEFAULT_CIPHER); 419 int cipher_name_len = strlen(ECRYPTFS_DEFAULT_CIPHER);
375 420
376 BUG_ON(cipher_name_len >= ECRYPTFS_MAX_CIPHER_NAME_SIZE); 421 BUG_ON(cipher_name_len >= ECRYPTFS_MAX_CIPHER_NAME_SIZE);
377
378 strcpy(mount_crypt_stat->global_default_cipher_name, 422 strcpy(mount_crypt_stat->global_default_cipher_name,
379 ECRYPTFS_DEFAULT_CIPHER); 423 ECRYPTFS_DEFAULT_CIPHER);
380 } 424 }
381 if (!cipher_key_bytes_set) { 425 if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)
426 && !fn_cipher_name_set)
427 strcpy(mount_crypt_stat->global_default_fn_cipher_name,
428 mount_crypt_stat->global_default_cipher_name);
429 if (!cipher_key_bytes_set)
382 mount_crypt_stat->global_default_cipher_key_size = 0; 430 mount_crypt_stat->global_default_cipher_key_size = 0;
383 } 431 if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)
432 && !fn_cipher_key_bytes_set)
433 mount_crypt_stat->global_default_fn_cipher_key_bytes =
434 mount_crypt_stat->global_default_cipher_key_size;
384 mutex_lock(&key_tfm_list_mutex); 435 mutex_lock(&key_tfm_list_mutex);
385 if (!ecryptfs_tfm_exists(mount_crypt_stat->global_default_cipher_name, 436 if (!ecryptfs_tfm_exists(mount_crypt_stat->global_default_cipher_name,
386 NULL)) 437 NULL)) {
387 rc = ecryptfs_add_new_key_tfm( 438 rc = ecryptfs_add_new_key_tfm(
388 NULL, mount_crypt_stat->global_default_cipher_name, 439 NULL, mount_crypt_stat->global_default_cipher_name,
389 mount_crypt_stat->global_default_cipher_key_size); 440 mount_crypt_stat->global_default_cipher_key_size);
390 mutex_unlock(&key_tfm_list_mutex); 441 if (rc) {
391 if (rc) { 442 printk(KERN_ERR "Error attempting to initialize "
392 printk(KERN_ERR "Error attempting to initialize cipher with " 443 "cipher with name = [%s] and key size = [%td]; "
393 "name = [%s] and key size = [%td]; rc = [%d]\n", 444 "rc = [%d]\n",
394 mount_crypt_stat->global_default_cipher_name, 445 mount_crypt_stat->global_default_cipher_name,
395 mount_crypt_stat->global_default_cipher_key_size, rc); 446 mount_crypt_stat->global_default_cipher_key_size,
396 rc = -EINVAL; 447 rc);
397 goto out; 448 rc = -EINVAL;
449 mutex_unlock(&key_tfm_list_mutex);
450 goto out;
451 }
398 } 452 }
453 if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)
454 && !ecryptfs_tfm_exists(
455 mount_crypt_stat->global_default_fn_cipher_name, NULL)) {
456 rc = ecryptfs_add_new_key_tfm(
457 NULL, mount_crypt_stat->global_default_fn_cipher_name,
458 mount_crypt_stat->global_default_fn_cipher_key_bytes);
459 if (rc) {
460 printk(KERN_ERR "Error attempting to initialize "
461 "cipher with name = [%s] and key size = [%td]; "
462 "rc = [%d]\n",
463 mount_crypt_stat->global_default_fn_cipher_name,
464 mount_crypt_stat->global_default_fn_cipher_key_bytes,
465 rc);
466 rc = -EINVAL;
467 mutex_unlock(&key_tfm_list_mutex);
468 goto out;
469 }
470 }
471 mutex_unlock(&key_tfm_list_mutex);
399 rc = ecryptfs_init_global_auth_toks(mount_crypt_stat); 472 rc = ecryptfs_init_global_auth_toks(mount_crypt_stat);
400 if (rc) { 473 if (rc)
401 printk(KERN_WARNING "One or more global auth toks could not " 474 printk(KERN_WARNING "One or more global auth toks could not "
402 "properly register; rc = [%d]\n", rc); 475 "properly register; rc = [%d]\n", rc);
403 }
404out: 476out:
405 return rc; 477 return rc;
406} 478}