diff options
author | Roberto Sassu <roberto.sassu@polito.it> | 2011-06-27 07:45:42 -0400 |
---|---|---|
committer | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2011-06-27 09:10:45 -0400 |
commit | 4e561d388feff18e4b798cef6a1a84a2cc7f20c2 (patch) | |
tree | 9208588c7d0e5e75766dd2c98e960840fdc8681e /security/keys | |
parent | 7103dff0e598cd634767f17a2958302c515700ca (diff) |
encrypted-keys: add key format support
This patch introduces a new parameter, called 'format', that defines the
format of data stored by encrypted keys. The 'default' format identifies
encrypted keys containing only the symmetric key, while other formats can
be defined to support additional information. The 'format' parameter is
written in the datablob produced by commands 'keyctl print' or
'keyctl pipe' and is integrity protected by the HMAC.
Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
Acked-by: Gianluca Ramunno <ramunno@polito.it>
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Diffstat (limited to 'security/keys')
-rw-r--r-- | security/keys/encrypted.c | 141 |
1 files changed, 101 insertions, 40 deletions
diff --git a/security/keys/encrypted.c b/security/keys/encrypted.c index f36a105de791..89981c987ba7 100644 --- a/security/keys/encrypted.c +++ b/security/keys/encrypted.c | |||
@@ -1,8 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2010 IBM Corporation | 2 | * Copyright (C) 2010 IBM Corporation |
3 | * Copyright (C) 2010 Politecnico di Torino, Italy | ||
4 | * TORSEC group -- http://security.polito.it | ||
3 | * | 5 | * |
4 | * Author: | 6 | * Authors: |
5 | * Mimi Zohar <zohar@us.ibm.com> | 7 | * Mimi Zohar <zohar@us.ibm.com> |
8 | * Roberto Sassu <roberto.sassu@polito.it> | ||
6 | * | 9 | * |
7 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
@@ -37,6 +40,7 @@ static const char KEY_USER_PREFIX[] = "user:"; | |||
37 | static const char hash_alg[] = "sha256"; | 40 | static const char hash_alg[] = "sha256"; |
38 | static const char hmac_alg[] = "hmac(sha256)"; | 41 | static const char hmac_alg[] = "hmac(sha256)"; |
39 | static const char blkcipher_alg[] = "cbc(aes)"; | 42 | static const char blkcipher_alg[] = "cbc(aes)"; |
43 | static const char key_format_default[] = "default"; | ||
40 | static unsigned int ivsize; | 44 | static unsigned int ivsize; |
41 | static int blksize; | 45 | static int blksize; |
42 | 46 | ||
@@ -58,6 +62,15 @@ enum { | |||
58 | Opt_err = -1, Opt_new, Opt_load, Opt_update | 62 | Opt_err = -1, Opt_new, Opt_load, Opt_update |
59 | }; | 63 | }; |
60 | 64 | ||
65 | enum { | ||
66 | Opt_error = -1, Opt_default | ||
67 | }; | ||
68 | |||
69 | static const match_table_t key_format_tokens = { | ||
70 | {Opt_default, "default"}, | ||
71 | {Opt_error, NULL} | ||
72 | }; | ||
73 | |||
61 | static const match_table_t key_tokens = { | 74 | static const match_table_t key_tokens = { |
62 | {Opt_new, "new"}, | 75 | {Opt_new, "new"}, |
63 | {Opt_load, "load"}, | 76 | {Opt_load, "load"}, |
@@ -118,8 +131,9 @@ out: | |||
118 | * datablob_parse - parse the keyctl data | 131 | * datablob_parse - parse the keyctl data |
119 | * | 132 | * |
120 | * datablob format: | 133 | * datablob format: |
121 | * new <master-key name> <decrypted data length> | 134 | * new [<format>] <master-key name> <decrypted data length> |
122 | * load <master-key name> <decrypted data length> <encrypted iv + data> | 135 | * load [<format>] <master-key name> <decrypted data length> |
136 | * <encrypted iv + data> | ||
123 | * update <new-master-key name> | 137 | * update <new-master-key name> |
124 | * | 138 | * |
125 | * Tokenizes a copy of the keyctl data, returning a pointer to each token, | 139 | * Tokenizes a copy of the keyctl data, returning a pointer to each token, |
@@ -127,13 +141,15 @@ out: | |||
127 | * | 141 | * |
128 | * On success returns 0, otherwise -EINVAL. | 142 | * On success returns 0, otherwise -EINVAL. |
129 | */ | 143 | */ |
130 | static int datablob_parse(char *datablob, char **master_desc, | 144 | static int datablob_parse(char *datablob, const char **format, |
131 | char **decrypted_datalen, char **hex_encoded_iv) | 145 | char **master_desc, char **decrypted_datalen, |
146 | char **hex_encoded_iv) | ||
132 | { | 147 | { |
133 | substring_t args[MAX_OPT_ARGS]; | 148 | substring_t args[MAX_OPT_ARGS]; |
134 | int ret = -EINVAL; | 149 | int ret = -EINVAL; |
135 | int key_cmd; | 150 | int key_cmd; |
136 | char *keyword; | 151 | int key_format; |
152 | char *p, *keyword; | ||
137 | 153 | ||
138 | keyword = strsep(&datablob, " \t"); | 154 | keyword = strsep(&datablob, " \t"); |
139 | if (!keyword) { | 155 | if (!keyword) { |
@@ -142,7 +158,24 @@ static int datablob_parse(char *datablob, char **master_desc, | |||
142 | } | 158 | } |
143 | key_cmd = match_token(keyword, key_tokens, args); | 159 | key_cmd = match_token(keyword, key_tokens, args); |
144 | 160 | ||
145 | *master_desc = strsep(&datablob, " \t"); | 161 | /* Get optional format: default */ |
162 | p = strsep(&datablob, " \t"); | ||
163 | if (!p) { | ||
164 | pr_err("encrypted_key: insufficient parameters specified\n"); | ||
165 | return ret; | ||
166 | } | ||
167 | |||
168 | key_format = match_token(p, key_format_tokens, args); | ||
169 | switch (key_format) { | ||
170 | case Opt_default: | ||
171 | *format = p; | ||
172 | *master_desc = strsep(&datablob, " \t"); | ||
173 | break; | ||
174 | case Opt_error: | ||
175 | *master_desc = p; | ||
176 | break; | ||
177 | } | ||
178 | |||
146 | if (!*master_desc) { | 179 | if (!*master_desc) { |
147 | pr_info("encrypted_key: master key parameter is missing\n"); | 180 | pr_info("encrypted_key: master key parameter is missing\n"); |
148 | goto out; | 181 | goto out; |
@@ -220,8 +253,8 @@ static char *datablob_format(struct encrypted_key_payload *epayload, | |||
220 | ascii_buf[asciiblob_len] = '\0'; | 253 | ascii_buf[asciiblob_len] = '\0'; |
221 | 254 | ||
222 | /* copy datablob master_desc and datalen strings */ | 255 | /* copy datablob master_desc and datalen strings */ |
223 | len = sprintf(ascii_buf, "%s %s ", epayload->master_desc, | 256 | len = sprintf(ascii_buf, "%s %s %s ", epayload->format, |
224 | epayload->datalen); | 257 | epayload->master_desc, epayload->datalen); |
225 | 258 | ||
226 | /* convert the hex encoded iv, encrypted-data and HMAC to ascii */ | 259 | /* convert the hex encoded iv, encrypted-data and HMAC to ascii */ |
227 | bufp = &ascii_buf[len]; | 260 | bufp = &ascii_buf[len]; |
@@ -464,9 +497,9 @@ static int datablob_hmac_append(struct encrypted_key_payload *epayload, | |||
464 | if (ret < 0) | 497 | if (ret < 0) |
465 | goto out; | 498 | goto out; |
466 | 499 | ||
467 | digest = epayload->master_desc + epayload->datablob_len; | 500 | digest = epayload->format + epayload->datablob_len; |
468 | ret = calc_hmac(digest, derived_key, sizeof derived_key, | 501 | ret = calc_hmac(digest, derived_key, sizeof derived_key, |
469 | epayload->master_desc, epayload->datablob_len); | 502 | epayload->format, epayload->datablob_len); |
470 | if (!ret) | 503 | if (!ret) |
471 | dump_hmac(NULL, digest, HASH_SIZE); | 504 | dump_hmac(NULL, digest, HASH_SIZE); |
472 | out: | 505 | out: |
@@ -475,26 +508,35 @@ out: | |||
475 | 508 | ||
476 | /* verify HMAC before decrypting encrypted key */ | 509 | /* verify HMAC before decrypting encrypted key */ |
477 | static int datablob_hmac_verify(struct encrypted_key_payload *epayload, | 510 | static int datablob_hmac_verify(struct encrypted_key_payload *epayload, |
478 | const u8 *master_key, size_t master_keylen) | 511 | const u8 *format, const u8 *master_key, |
512 | size_t master_keylen) | ||
479 | { | 513 | { |
480 | u8 derived_key[HASH_SIZE]; | 514 | u8 derived_key[HASH_SIZE]; |
481 | u8 digest[HASH_SIZE]; | 515 | u8 digest[HASH_SIZE]; |
482 | int ret; | 516 | int ret; |
517 | char *p; | ||
518 | unsigned short len; | ||
483 | 519 | ||
484 | ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen); | 520 | ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen); |
485 | if (ret < 0) | 521 | if (ret < 0) |
486 | goto out; | 522 | goto out; |
487 | 523 | ||
488 | ret = calc_hmac(digest, derived_key, sizeof derived_key, | 524 | len = epayload->datablob_len; |
489 | epayload->master_desc, epayload->datablob_len); | 525 | if (!format) { |
526 | p = epayload->master_desc; | ||
527 | len -= strlen(epayload->format) + 1; | ||
528 | } else | ||
529 | p = epayload->format; | ||
530 | |||
531 | ret = calc_hmac(digest, derived_key, sizeof derived_key, p, len); | ||
490 | if (ret < 0) | 532 | if (ret < 0) |
491 | goto out; | 533 | goto out; |
492 | ret = memcmp(digest, epayload->master_desc + epayload->datablob_len, | 534 | ret = memcmp(digest, epayload->format + epayload->datablob_len, |
493 | sizeof digest); | 535 | sizeof digest); |
494 | if (ret) { | 536 | if (ret) { |
495 | ret = -EINVAL; | 537 | ret = -EINVAL; |
496 | dump_hmac("datablob", | 538 | dump_hmac("datablob", |
497 | epayload->master_desc + epayload->datablob_len, | 539 | epayload->format + epayload->datablob_len, |
498 | HASH_SIZE); | 540 | HASH_SIZE); |
499 | dump_hmac("calc", digest, HASH_SIZE); | 541 | dump_hmac("calc", digest, HASH_SIZE); |
500 | } | 542 | } |
@@ -539,13 +581,16 @@ out: | |||
539 | 581 | ||
540 | /* Allocate memory for decrypted key and datablob. */ | 582 | /* Allocate memory for decrypted key and datablob. */ |
541 | static struct encrypted_key_payload *encrypted_key_alloc(struct key *key, | 583 | static struct encrypted_key_payload *encrypted_key_alloc(struct key *key, |
584 | const char *format, | ||
542 | const char *master_desc, | 585 | const char *master_desc, |
543 | const char *datalen) | 586 | const char *datalen) |
544 | { | 587 | { |
545 | struct encrypted_key_payload *epayload = NULL; | 588 | struct encrypted_key_payload *epayload = NULL; |
546 | unsigned short datablob_len; | 589 | unsigned short datablob_len; |
547 | unsigned short decrypted_datalen; | 590 | unsigned short decrypted_datalen; |
591 | unsigned short payload_datalen; | ||
548 | unsigned int encrypted_datalen; | 592 | unsigned int encrypted_datalen; |
593 | unsigned int format_len; | ||
549 | long dlen; | 594 | long dlen; |
550 | int ret; | 595 | int ret; |
551 | 596 | ||
@@ -553,29 +598,32 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key, | |||
553 | if (ret < 0 || dlen < MIN_DATA_SIZE || dlen > MAX_DATA_SIZE) | 598 | if (ret < 0 || dlen < MIN_DATA_SIZE || dlen > MAX_DATA_SIZE) |
554 | return ERR_PTR(-EINVAL); | 599 | return ERR_PTR(-EINVAL); |
555 | 600 | ||
601 | format_len = (!format) ? strlen(key_format_default) : strlen(format); | ||
556 | decrypted_datalen = dlen; | 602 | decrypted_datalen = dlen; |
603 | payload_datalen = decrypted_datalen; | ||
557 | encrypted_datalen = roundup(decrypted_datalen, blksize); | 604 | encrypted_datalen = roundup(decrypted_datalen, blksize); |
558 | 605 | ||
559 | datablob_len = strlen(master_desc) + 1 + strlen(datalen) + 1 | 606 | datablob_len = format_len + 1 + strlen(master_desc) + 1 |
560 | + ivsize + 1 + encrypted_datalen; | 607 | + strlen(datalen) + 1 + ivsize + 1 + encrypted_datalen; |
561 | 608 | ||
562 | ret = key_payload_reserve(key, decrypted_datalen + datablob_len | 609 | ret = key_payload_reserve(key, payload_datalen + datablob_len |
563 | + HASH_SIZE + 1); | 610 | + HASH_SIZE + 1); |
564 | if (ret < 0) | 611 | if (ret < 0) |
565 | return ERR_PTR(ret); | 612 | return ERR_PTR(ret); |
566 | 613 | ||
567 | epayload = kzalloc(sizeof(*epayload) + decrypted_datalen + | 614 | epayload = kzalloc(sizeof(*epayload) + payload_datalen + |
568 | datablob_len + HASH_SIZE + 1, GFP_KERNEL); | 615 | datablob_len + HASH_SIZE + 1, GFP_KERNEL); |
569 | if (!epayload) | 616 | if (!epayload) |
570 | return ERR_PTR(-ENOMEM); | 617 | return ERR_PTR(-ENOMEM); |
571 | 618 | ||
619 | epayload->payload_datalen = payload_datalen; | ||
572 | epayload->decrypted_datalen = decrypted_datalen; | 620 | epayload->decrypted_datalen = decrypted_datalen; |
573 | epayload->datablob_len = datablob_len; | 621 | epayload->datablob_len = datablob_len; |
574 | return epayload; | 622 | return epayload; |
575 | } | 623 | } |
576 | 624 | ||
577 | static int encrypted_key_decrypt(struct encrypted_key_payload *epayload, | 625 | static int encrypted_key_decrypt(struct encrypted_key_payload *epayload, |
578 | const char *hex_encoded_iv) | 626 | const char *format, const char *hex_encoded_iv) |
579 | { | 627 | { |
580 | struct key *mkey; | 628 | struct key *mkey; |
581 | u8 derived_key[HASH_SIZE]; | 629 | u8 derived_key[HASH_SIZE]; |
@@ -596,14 +644,14 @@ static int encrypted_key_decrypt(struct encrypted_key_payload *epayload, | |||
596 | hex2bin(epayload->iv, hex_encoded_iv, ivsize); | 644 | hex2bin(epayload->iv, hex_encoded_iv, ivsize); |
597 | hex2bin(epayload->encrypted_data, hex_encoded_data, encrypted_datalen); | 645 | hex2bin(epayload->encrypted_data, hex_encoded_data, encrypted_datalen); |
598 | 646 | ||
599 | hmac = epayload->master_desc + epayload->datablob_len; | 647 | hmac = epayload->format + epayload->datablob_len; |
600 | hex2bin(hmac, hex_encoded_data + (encrypted_datalen * 2), HASH_SIZE); | 648 | hex2bin(hmac, hex_encoded_data + (encrypted_datalen * 2), HASH_SIZE); |
601 | 649 | ||
602 | mkey = request_master_key(epayload, &master_key, &master_keylen); | 650 | mkey = request_master_key(epayload, &master_key, &master_keylen); |
603 | if (IS_ERR(mkey)) | 651 | if (IS_ERR(mkey)) |
604 | return PTR_ERR(mkey); | 652 | return PTR_ERR(mkey); |
605 | 653 | ||
606 | ret = datablob_hmac_verify(epayload, master_key, master_keylen); | 654 | ret = datablob_hmac_verify(epayload, format, master_key, master_keylen); |
607 | if (ret < 0) { | 655 | if (ret < 0) { |
608 | pr_err("encrypted_key: bad hmac (%d)\n", ret); | 656 | pr_err("encrypted_key: bad hmac (%d)\n", ret); |
609 | goto out; | 657 | goto out; |
@@ -623,14 +671,23 @@ out: | |||
623 | } | 671 | } |
624 | 672 | ||
625 | static void __ekey_init(struct encrypted_key_payload *epayload, | 673 | static void __ekey_init(struct encrypted_key_payload *epayload, |
626 | const char *master_desc, const char *datalen) | 674 | const char *format, const char *master_desc, |
675 | const char *datalen) | ||
627 | { | 676 | { |
628 | epayload->master_desc = epayload->decrypted_data | 677 | unsigned int format_len; |
629 | + epayload->decrypted_datalen; | 678 | |
679 | format_len = (!format) ? strlen(key_format_default) : strlen(format); | ||
680 | epayload->format = epayload->payload_data + epayload->payload_datalen; | ||
681 | epayload->master_desc = epayload->format + format_len + 1; | ||
630 | epayload->datalen = epayload->master_desc + strlen(master_desc) + 1; | 682 | epayload->datalen = epayload->master_desc + strlen(master_desc) + 1; |
631 | epayload->iv = epayload->datalen + strlen(datalen) + 1; | 683 | epayload->iv = epayload->datalen + strlen(datalen) + 1; |
632 | epayload->encrypted_data = epayload->iv + ivsize + 1; | 684 | epayload->encrypted_data = epayload->iv + ivsize + 1; |
685 | epayload->decrypted_data = epayload->payload_data; | ||
633 | 686 | ||
687 | if (!format) | ||
688 | memcpy(epayload->format, key_format_default, format_len); | ||
689 | else | ||
690 | memcpy(epayload->format, format, format_len); | ||
634 | memcpy(epayload->master_desc, master_desc, strlen(master_desc)); | 691 | memcpy(epayload->master_desc, master_desc, strlen(master_desc)); |
635 | memcpy(epayload->datalen, datalen, strlen(datalen)); | 692 | memcpy(epayload->datalen, datalen, strlen(datalen)); |
636 | } | 693 | } |
@@ -642,19 +699,19 @@ static void __ekey_init(struct encrypted_key_payload *epayload, | |||
642 | * itself. For an old key, decrypt the hex encoded data. | 699 | * itself. For an old key, decrypt the hex encoded data. |
643 | */ | 700 | */ |
644 | static int encrypted_init(struct encrypted_key_payload *epayload, | 701 | static int encrypted_init(struct encrypted_key_payload *epayload, |
645 | const char *master_desc, const char *datalen, | 702 | const char *format, const char *master_desc, |
646 | const char *hex_encoded_iv) | 703 | const char *datalen, const char *hex_encoded_iv) |
647 | { | 704 | { |
648 | int ret = 0; | 705 | int ret = 0; |
649 | 706 | ||
650 | __ekey_init(epayload, master_desc, datalen); | 707 | __ekey_init(epayload, format, master_desc, datalen); |
651 | if (!hex_encoded_iv) { | 708 | if (!hex_encoded_iv) { |
652 | get_random_bytes(epayload->iv, ivsize); | 709 | get_random_bytes(epayload->iv, ivsize); |
653 | 710 | ||
654 | get_random_bytes(epayload->decrypted_data, | 711 | get_random_bytes(epayload->decrypted_data, |
655 | epayload->decrypted_datalen); | 712 | epayload->decrypted_datalen); |
656 | } else | 713 | } else |
657 | ret = encrypted_key_decrypt(epayload, hex_encoded_iv); | 714 | ret = encrypted_key_decrypt(epayload, format, hex_encoded_iv); |
658 | return ret; | 715 | return ret; |
659 | } | 716 | } |
660 | 717 | ||
@@ -671,6 +728,7 @@ static int encrypted_instantiate(struct key *key, const void *data, | |||
671 | { | 728 | { |
672 | struct encrypted_key_payload *epayload = NULL; | 729 | struct encrypted_key_payload *epayload = NULL; |
673 | char *datablob = NULL; | 730 | char *datablob = NULL; |
731 | const char *format = NULL; | ||
674 | char *master_desc = NULL; | 732 | char *master_desc = NULL; |
675 | char *decrypted_datalen = NULL; | 733 | char *decrypted_datalen = NULL; |
676 | char *hex_encoded_iv = NULL; | 734 | char *hex_encoded_iv = NULL; |
@@ -684,17 +742,18 @@ static int encrypted_instantiate(struct key *key, const void *data, | |||
684 | return -ENOMEM; | 742 | return -ENOMEM; |
685 | datablob[datalen] = 0; | 743 | datablob[datalen] = 0; |
686 | memcpy(datablob, data, datalen); | 744 | memcpy(datablob, data, datalen); |
687 | ret = datablob_parse(datablob, &master_desc, &decrypted_datalen, | 745 | ret = datablob_parse(datablob, &format, &master_desc, |
688 | &hex_encoded_iv); | 746 | &decrypted_datalen, &hex_encoded_iv); |
689 | if (ret < 0) | 747 | if (ret < 0) |
690 | goto out; | 748 | goto out; |
691 | 749 | ||
692 | epayload = encrypted_key_alloc(key, master_desc, decrypted_datalen); | 750 | epayload = encrypted_key_alloc(key, format, master_desc, |
751 | decrypted_datalen); | ||
693 | if (IS_ERR(epayload)) { | 752 | if (IS_ERR(epayload)) { |
694 | ret = PTR_ERR(epayload); | 753 | ret = PTR_ERR(epayload); |
695 | goto out; | 754 | goto out; |
696 | } | 755 | } |
697 | ret = encrypted_init(epayload, master_desc, decrypted_datalen, | 756 | ret = encrypted_init(epayload, format, master_desc, decrypted_datalen, |
698 | hex_encoded_iv); | 757 | hex_encoded_iv); |
699 | if (ret < 0) { | 758 | if (ret < 0) { |
700 | kfree(epayload); | 759 | kfree(epayload); |
@@ -731,6 +790,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen) | |||
731 | struct encrypted_key_payload *new_epayload; | 790 | struct encrypted_key_payload *new_epayload; |
732 | char *buf; | 791 | char *buf; |
733 | char *new_master_desc = NULL; | 792 | char *new_master_desc = NULL; |
793 | const char *format = NULL; | ||
734 | int ret = 0; | 794 | int ret = 0; |
735 | 795 | ||
736 | if (datalen <= 0 || datalen > 32767 || !data) | 796 | if (datalen <= 0 || datalen > 32767 || !data) |
@@ -742,7 +802,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen) | |||
742 | 802 | ||
743 | buf[datalen] = 0; | 803 | buf[datalen] = 0; |
744 | memcpy(buf, data, datalen); | 804 | memcpy(buf, data, datalen); |
745 | ret = datablob_parse(buf, &new_master_desc, NULL, NULL); | 805 | ret = datablob_parse(buf, &format, &new_master_desc, NULL, NULL); |
746 | if (ret < 0) | 806 | if (ret < 0) |
747 | goto out; | 807 | goto out; |
748 | 808 | ||
@@ -750,18 +810,19 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen) | |||
750 | if (ret < 0) | 810 | if (ret < 0) |
751 | goto out; | 811 | goto out; |
752 | 812 | ||
753 | new_epayload = encrypted_key_alloc(key, new_master_desc, | 813 | new_epayload = encrypted_key_alloc(key, epayload->format, |
754 | epayload->datalen); | 814 | new_master_desc, epayload->datalen); |
755 | if (IS_ERR(new_epayload)) { | 815 | if (IS_ERR(new_epayload)) { |
756 | ret = PTR_ERR(new_epayload); | 816 | ret = PTR_ERR(new_epayload); |
757 | goto out; | 817 | goto out; |
758 | } | 818 | } |
759 | 819 | ||
760 | __ekey_init(new_epayload, new_master_desc, epayload->datalen); | 820 | __ekey_init(new_epayload, epayload->format, new_master_desc, |
821 | epayload->datalen); | ||
761 | 822 | ||
762 | memcpy(new_epayload->iv, epayload->iv, ivsize); | 823 | memcpy(new_epayload->iv, epayload->iv, ivsize); |
763 | memcpy(new_epayload->decrypted_data, epayload->decrypted_data, | 824 | memcpy(new_epayload->payload_data, epayload->payload_data, |
764 | epayload->decrypted_datalen); | 825 | epayload->payload_datalen); |
765 | 826 | ||
766 | rcu_assign_pointer(key->payload.data, new_epayload); | 827 | rcu_assign_pointer(key->payload.data, new_epayload); |
767 | call_rcu(&epayload->rcu, encrypted_rcu_free); | 828 | call_rcu(&epayload->rcu, encrypted_rcu_free); |