OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "crypto/openpgp_symmetric_encryption.h" | 5 #include "crypto/openpgp_symmetric_encryption.h" |
6 | 6 |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 | 8 |
9 #include <sechash.h> | 9 #include <sechash.h> |
10 #include <cryptohi.h> | 10 #include <cryptohi.h> |
11 | 11 |
12 #include <vector> | 12 #include <vector> |
13 | 13 |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/rand_util.h" | 15 #include "crypto/random.h" |
16 #include "crypto/scoped_nss_types.h" | 16 #include "crypto/scoped_nss_types.h" |
17 #include "crypto/nss_util.h" | 17 #include "crypto/nss_util.h" |
18 | 18 |
19 namespace crypto { | 19 namespace crypto { |
20 | 20 |
21 namespace { | 21 namespace { |
22 | 22 |
23 // Reader wraps a StringPiece and provides methods to read several datatypes | 23 // Reader wraps a StringPiece and provides methods to read several datatypes |
24 // while advancing the StringPiece. | 24 // while advancing the StringPiece. |
25 class Reader { | 25 class Reader { |
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
673 // |passphrase|, sets |out_key| to it and returns a Symmetric Key Encrypted | 673 // |passphrase|, sets |out_key| to it and returns a Symmetric Key Encrypted |
674 // packet. See RFC 4880, section 5.3. | 674 // packet. See RFC 4880, section 5.3. |
675 static ByteString SerializeSymmetricKeyEncrypted(base::StringPiece passphrase, | 675 static ByteString SerializeSymmetricKeyEncrypted(base::StringPiece passphrase, |
676 ByteString *out_key) { | 676 ByteString *out_key) { |
677 ByteString ske; | 677 ByteString ske; |
678 ske.push_back(4); // version 4 | 678 ske.push_back(4); // version 4 |
679 ske.push_back(7); // AES-128 | 679 ske.push_back(7); // AES-128 |
680 ske.push_back(3); // iterated and salted S2K | 680 ske.push_back(3); // iterated and salted S2K |
681 ske.push_back(2); // SHA-1 | 681 ske.push_back(2); // SHA-1 |
682 | 682 |
683 uint64 salt64 = base::RandUint64(); | 683 uint64 salt64; |
| 684 crypto::RandBytes(&salt64, sizeof(salt64)); |
684 ByteString salt(sizeof(salt64), 0); | 685 ByteString salt(sizeof(salt64), 0); |
685 | 686 |
686 // It's a random value, so endianness doesn't matter. | 687 // It's a random value, so endianness doesn't matter. |
687 ske += ByteString(reinterpret_cast<uint8*>(&salt64), sizeof(salt64)); | 688 ske += ByteString(reinterpret_cast<uint8*>(&salt64), sizeof(salt64)); |
688 ske.push_back(96); // iteration count of 65536 | 689 ske.push_back(96); // iteration count of 65536 |
689 | 690 |
690 uint8 key[16]; | 691 uint8 key[16]; |
691 SaltedIteratedS2K( | 692 SaltedIteratedS2K( |
692 sizeof(key), HASH_AlgSHA1, passphrase, | 693 sizeof(key), HASH_AlgSHA1, passphrase, |
693 base::StringPiece(reinterpret_cast<char*>(&salt64), sizeof(salt64)), | 694 base::StringPiece(reinterpret_cast<char*>(&salt64), sizeof(salt64)), |
694 65536, key); | 695 65536, key); |
695 *out_key = ByteString(key, sizeof(key)); | 696 *out_key = ByteString(key, sizeof(key)); |
696 return MakePacket(kSymmetricKeyEncryptedTag, ske); | 697 return MakePacket(kSymmetricKeyEncryptedTag, ske); |
697 } | 698 } |
698 | 699 |
699 // SerializeSymmetricallyEncrypted encrypts |plaintext| with |key| and | 700 // SerializeSymmetricallyEncrypted encrypts |plaintext| with |key| and |
700 // returns a Symmetrically Encrypted packet containing the ciphertext. See | 701 // returns a Symmetrically Encrypted packet containing the ciphertext. See |
701 // RFC 4880, section 5.7. | 702 // RFC 4880, section 5.7. |
702 static ByteString SerializeSymmetricallyEncrypted(ByteString plaintext, | 703 static ByteString SerializeSymmetricallyEncrypted(ByteString plaintext, |
703 const ByteString& key) { | 704 const ByteString& key) { |
704 // We need this for PK11_CipherOp to write to, but we never check it as we | 705 // We need this for PK11_CipherOp to write to, but we never check it as we |
705 // work in ECB mode, one block at a time. | 706 // work in ECB mode, one block at a time. |
706 int out_len; | 707 int out_len; |
707 | 708 |
708 ByteString packet; | 709 ByteString packet; |
709 packet.push_back(1); // version 1 | 710 packet.push_back(1); // version 1 |
710 static const unsigned kBlockSize = 16; // AES block size | 711 static const unsigned kBlockSize = 16; // AES block size |
711 | 712 |
712 uint8 prefix[kBlockSize + 2], fre[kBlockSize], iv[kBlockSize]; | 713 uint8 prefix[kBlockSize + 2], fre[kBlockSize], iv[kBlockSize]; |
713 base::RandBytes(iv, kBlockSize); | 714 crypto::RandBytes(iv, kBlockSize); |
714 memset(fre, 0, sizeof(fre)); | 715 memset(fre, 0, sizeof(fre)); |
715 | 716 |
716 ScopedPK11Context aes_context; | 717 ScopedPK11Context aes_context; |
717 CHECK(CreateAESContext(key.data(), key.size(), &aes_context)); | 718 CHECK(CreateAESContext(key.data(), key.size(), &aes_context)); |
718 | 719 |
719 PK11_CipherOp(aes_context.get(), fre, &out_len, sizeof(fre), fre, | 720 PK11_CipherOp(aes_context.get(), fre, &out_len, sizeof(fre), fre, |
720 AES_BLOCK_SIZE); | 721 AES_BLOCK_SIZE); |
721 for (unsigned i = 0; i < 16; i++) | 722 for (unsigned i = 0; i < 16; i++) |
722 prefix[i] = iv[i] ^ fre[i]; | 723 prefix[i] = iv[i] ^ fre[i]; |
723 PK11_CipherOp(aes_context.get(), fre, &out_len, sizeof(fre), prefix, | 724 PK11_CipherOp(aes_context.get(), fre, &out_len, sizeof(fre), prefix, |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 base::StringPiece plaintext, | 786 base::StringPiece plaintext, |
786 base::StringPiece passphrase) { | 787 base::StringPiece passphrase) { |
787 EnsureNSSInit(); | 788 EnsureNSSInit(); |
788 | 789 |
789 Encrypter::ByteString b = | 790 Encrypter::ByteString b = |
790 Encrypter::Encrypt(plaintext, passphrase); | 791 Encrypter::Encrypt(plaintext, passphrase); |
791 return std::string(reinterpret_cast<const char*>(b.data()), b.size()); | 792 return std::string(reinterpret_cast<const char*>(b.data()), b.size()); |
792 } | 793 } |
793 | 794 |
794 } // namespace crypto | 795 } // namespace crypto |
OLD | NEW |