diff options
Diffstat (limited to 'fs/ecryptfs/main.c')
| -rw-r--r-- | fs/ecryptfs/main.c | 126 |
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 | ||
| 211 | static const match_table_t tokens = { | 213 | static 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 | } | ||
| 404 | out: | 476 | out: |
| 405 | return rc; | 477 | return rc; |
| 406 | } | 478 | } |
