Commit 87c94c4df0149786ad91d8a03c738a03369ee9c8

Authored by Michael Halcrow
Committed by Linus Torvalds
1 parent addd65ad8d

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>

Showing 1 changed file with 99 additions and 27 deletions Side-by-side Diff

... ... @@ -206,7 +206,9 @@
206 206 ecryptfs_opt_cipher, ecryptfs_opt_ecryptfs_cipher,
207 207 ecryptfs_opt_ecryptfs_key_bytes,
208 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  
211 213 static const match_table_t tokens = {
212 214 {ecryptfs_opt_sig, "sig=%s"},
... ... @@ -217,6 +219,9 @@
217 219 {ecryptfs_opt_passthrough, "ecryptfs_passthrough"},
218 220 {ecryptfs_opt_xattr_metadata, "ecryptfs_xattr_metadata"},
219 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 225 {ecryptfs_opt_err, NULL}
221 226 };
222 227  
223 228  
... ... @@ -281,8 +286,11 @@
281 286 int rc = 0;
282 287 int sig_set = 0;
283 288 int cipher_name_set = 0;
  289 + int fn_cipher_name_set = 0;
284 290 int cipher_key_bytes;
285 291 int cipher_key_bytes_set = 0;
  292 + int fn_cipher_key_bytes;
  293 + int fn_cipher_key_bytes_set = 0;
286 294 struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
287 295 &ecryptfs_superblock_to_private(sb)->mount_crypt_stat;
288 296 substring_t args[MAX_OPT_ARGS];
289 297  
... ... @@ -290,7 +298,12 @@
290 298 char *sig_src;
291 299 char *cipher_name_dst;
292 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 305 char *cipher_key_bytes_src;
  306 + char *fn_cipher_key_bytes_src;
294 307  
295 308 if (!options) {
296 309 rc = -EINVAL;
... ... @@ -322,10 +335,7 @@
322 335 global_default_cipher_name;
323 336 strncpy(cipher_name_dst, cipher_name_src,
324 337 ECRYPTFS_MAX_CIPHER_NAME_SIZE);
325   - ecryptfs_printk(KERN_DEBUG,
326   - "The mount_crypt_stat "
327   - "global_default_cipher_name set to: "
328   - "[%s]\n", cipher_name_dst);
  338 + cipher_name_dst[ECRYPTFS_MAX_CIPHER_NAME_SIZE] = '\0';
329 339 cipher_name_set = 1;
330 340 break;
331 341 case ecryptfs_opt_ecryptfs_key_bytes:
... ... @@ -335,11 +345,6 @@
335 345 &cipher_key_bytes_src, 0);
336 346 mount_crypt_stat->global_default_cipher_key_size =
337 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 348 cipher_key_bytes_set = 1;
344 349 break;
345 350 case ecryptfs_opt_passthrough:
346 351  
... ... @@ -356,11 +361,51 @@
356 361 mount_crypt_stat->flags |=
357 362 ECRYPTFS_ENCRYPTED_VIEW_ENABLED;
358 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 404 case ecryptfs_opt_err:
360 405 default:
361   - ecryptfs_printk(KERN_WARNING,
362   - "eCryptfs: unrecognized option '%s'\n",
363   - p);
  406 + printk(KERN_WARNING
  407 + "%s: eCryptfs: unrecognized option [%s]\n",
  408 + __func__, p);
364 409 }
365 410 }
366 411 if (!sig_set) {
367 412  
368 413  
369 414  
370 415  
371 416  
372 417  
373 418  
... ... @@ -374,33 +419,60 @@
374 419 int cipher_name_len = strlen(ECRYPTFS_DEFAULT_CIPHER);
375 420  
376 421 BUG_ON(cipher_name_len >= ECRYPTFS_MAX_CIPHER_NAME_SIZE);
377   -
378 422 strcpy(mount_crypt_stat->global_default_cipher_name,
379 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 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 435 mutex_lock(&key_tfm_list_mutex);
385 436 if (!ecryptfs_tfm_exists(mount_crypt_stat->global_default_cipher_name,
386   - NULL))
  437 + NULL)) {
387 438 rc = ecryptfs_add_new_key_tfm(
388 439 NULL, mount_crypt_stat->global_default_cipher_name,
389 440 mount_crypt_stat->global_default_cipher_key_size);
390   - mutex_unlock(&key_tfm_list_mutex);
391   - if (rc) {
392   - printk(KERN_ERR "Error attempting to initialize cipher with "
393   - "name = [%s] and key size = [%td]; rc = [%d]\n",
394   - mount_crypt_stat->global_default_cipher_name,
395   - mount_crypt_stat->global_default_cipher_key_size, rc);
396   - rc = -EINVAL;
397   - goto out;
  441 + if (rc) {
  442 + printk(KERN_ERR "Error attempting to initialize "
  443 + "cipher with name = [%s] and key size = [%td]; "
  444 + "rc = [%d]\n",
  445 + mount_crypt_stat->global_default_cipher_name,
  446 + mount_crypt_stat->global_default_cipher_key_size,
  447 + rc);
  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 472 rc = ecryptfs_init_global_auth_toks(mount_crypt_stat);
400   - if (rc) {
  473 + if (rc)
401 474 printk(KERN_WARNING "One or more global auth toks could not "
402 475 "properly register; rc = [%d]\n", rc);
403   - }
404 476 out:
405 477 return rc;
406 478 }