// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "net/quic/crypto/crypto_secret_boxer.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "crypto/secure_hash.h" #include "crypto/sha2.h" #include "net/quic/crypto/quic_random.h" using base::StringPiece; using std::string; namespace net { // Defined kKeySize for GetKeySize() and SetKey(). static const size_t kKeySize = 16; // kBoxNonceSize contains the number of bytes of nonce that we use in each box. static const size_t kBoxNonceSize = 16; // static size_t CryptoSecretBoxer::GetKeySize() { return kKeySize; } void CryptoSecretBoxer::SetKey(StringPiece key) { DCHECK_EQ(static_cast(kKeySize), key.size()); key_ = key.as_string(); } // TODO(rtenneti): Delete sha256 based code. Use Aes128Gcm12Encrypter to Box the // plaintext. This is temporary solution for tests to pass. string CryptoSecretBoxer::Box(QuicRandom* rand, StringPiece plaintext) const { string ret; const size_t len = kBoxNonceSize + plaintext.size() + crypto::kSHA256Length; ret.resize(len); char* data = &ret[0]; // Generate nonce. rand->RandBytes(data, kBoxNonceSize); memcpy(data + kBoxNonceSize, plaintext.data(), plaintext.size()); // Compute sha256 for nonce + plaintext. scoped_ptr sha256(crypto::SecureHash::Create( crypto::SecureHash::SHA256)); sha256->Update(data, kBoxNonceSize + plaintext.size()); sha256->Finish(data + kBoxNonceSize + plaintext.size(), crypto::kSHA256Length); return ret; } // TODO(rtenneti): Delete sha256 based code. Use Aes128Gcm12Decrypter to Unbox // the plaintext. This is temporary solution for tests to pass. bool CryptoSecretBoxer::Unbox(StringPiece ciphertext, string* out_storage, StringPiece* out) const { if (ciphertext.size() < kBoxNonceSize + crypto::kSHA256Length) { return false; } const size_t plaintext_len = ciphertext.size() - kBoxNonceSize - crypto::kSHA256Length; out_storage->resize(plaintext_len); char* data = const_cast(out_storage->data()); // Copy plaintext from ciphertext. if (plaintext_len != 0) { memcpy(data, ciphertext.data() + kBoxNonceSize, plaintext_len); } // Compute sha256 for nonce + plaintext. scoped_ptr sha256(crypto::SecureHash::Create( crypto::SecureHash::SHA256)); sha256->Update(ciphertext.data(), ciphertext.size() - crypto::kSHA256Length); char sha256_bytes[crypto::kSHA256Length]; sha256->Finish(sha256_bytes, sizeof(sha256_bytes)); // Verify sha256. if (0 != memcmp(ciphertext.data() + ciphertext.size() - crypto::kSHA256Length, sha256_bytes, crypto::kSHA256Length)) { return false; } out->set(data, plaintext_len); return true; } } // namespace net