Index: crypto.cc |
diff --git a/crypto.cc b/crypto.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7bd4b762b82443a0803a4853f3f4ee22537dc22a |
--- /dev/null |
+++ b/crypto.cc |
@@ -0,0 +1,109 @@ |
+// Copyright (c) 2009-2010 The Chromium OS Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+// Contains the implementation of class Crypto |
+ |
+#include "crypto.h" |
+ |
+#include <openssl/err.h> |
+#include <openssl/evp.h> |
+#include <openssl/rand.h> |
+#include <openssl/rsa.h> |
+#include <openssl/sha.h> |
+ |
+#include <base/file_util.h> |
+#include <base/logging.h> |
+#include <chromeos/utility.h> |
+ |
+using std::string; |
+ |
+namespace tpm_init { |
+ |
+const std::string kDefaultEntropySource = "/dev/urandom"; |
+const int kWellKnownExponent = 65537; |
+ |
+Crypto::Crypto() |
+ : entropy_source_(kDefaultEntropySource) { |
+} |
+ |
+Crypto::~Crypto() { |
+} |
+ |
+bool Crypto::Init() { |
+ SeedRng(); |
+ return true; |
+} |
+ |
+void Crypto::SeedRng() const { |
+ // TODO(fes): Get assistance from the TPM? |
+ while (!RAND_status()) { |
+ char buffer[256]; |
+ file_util::ReadFile(FilePath(entropy_source_), buffer, sizeof(buffer)); |
+ RAND_add(buffer, sizeof(buffer), sizeof(buffer)); |
+ } |
+} |
+ |
+void Crypto::GetSecureRandom(unsigned char *rand, int length) const { |
+ SeedRng(); |
+ // Have OpenSSL generate the random bytes |
+ RAND_bytes(rand, length); |
+} |
+ |
+void Crypto::GetSha1(const chromeos::Blob& data, int start, int count, |
+ SecureBlob* hash) const { |
+ SHA_CTX sha_ctx; |
+ unsigned char md_value[SHA_DIGEST_LENGTH]; |
+ |
+ SHA1_Init(&sha_ctx); |
+ SHA1_Update(&sha_ctx, &data[start], count); |
+ SHA1_Final(md_value, &sha_ctx); |
+ hash->resize(sizeof(md_value)); |
+ memcpy(hash->data(), md_value, sizeof(md_value)); |
+} |
+ |
+bool Crypto::CreateRsaKey(int key_bits, SecureBlob* n, SecureBlob* p) const { |
+ SeedRng(); |
+ |
+ RSA* rsa = RSA_generate_key(key_bits, kWellKnownExponent, NULL, NULL); |
+ |
+ if (rsa == NULL) { |
+ LOG(ERROR) << "RSA key generation failed."; |
+ return false; |
+ } |
+ |
+ SecureBlob local_n(BN_num_bytes(rsa->n)); |
+ if (BN_bn2bin(rsa->n, static_cast<unsigned char*>(local_n.data())) <= 0) { |
+ LOG(ERROR) << "Unable to get modulus from RSA key."; |
+ RSA_free(rsa); |
+ return false; |
+ } |
+ |
+ SecureBlob local_p(BN_num_bytes(rsa->p)); |
+ if (BN_bn2bin(rsa->p, static_cast<unsigned char*>(local_p.data())) <= 0) { |
+ LOG(ERROR) << "Unable to get private key from RSA key."; |
+ RSA_free(rsa); |
+ return false; |
+ } |
+ |
+ RSA_free(rsa); |
+ n->swap(local_n); |
+ p->swap(local_p); |
+ return true; |
+} |
+ |
+void Crypto::AsciiEncodeToBuffer(const chromeos::Blob& blob, char* buffer, |
+ int buffer_length) { |
+ const char hex_chars[] = "0123456789abcdef"; |
+ int i = 0; |
+ for (chromeos::Blob::const_iterator it = blob.begin(); |
+ it < blob.end() && (i + 1) < buffer_length; ++it) { |
+ buffer[i++] = hex_chars[((*it) >> 4) & 0x0f]; |
+ buffer[i++] = hex_chars[(*it) & 0x0f]; |
+ } |
+ if (i < buffer_length) { |
+ buffer[i] = '\0'; |
+ } |
+} |
+ |
+} // namespace tpm_init |