1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "crypto/secure_hash.h" 6 7 #include <openssl/crypto.h> 8 #include <openssl/sha.h> 9 10 #include "base/basictypes.h" 11 #include "base/logging.h" 12 #include "base/pickle.h" 13 #include "crypto/openssl_util.h" 14 15 namespace crypto { 16 17 namespace { 18 19 const char kSHA256Descriptor[] = "OpenSSL"; 20 21 class SecureHashSHA256OpenSSL : public SecureHash { 22 public: 23 static const int kSecureHashVersion = 1; 24 25 SecureHashSHA256OpenSSL() { 26 SHA256_Init(&ctx_); 27 } 28 29 virtual ~SecureHashSHA256OpenSSL() { 30 OPENSSL_cleanse(&ctx_, sizeof(ctx_)); 31 } 32 33 virtual void Update(const void* input, size_t len) OVERRIDE { 34 SHA256_Update(&ctx_, static_cast<const unsigned char*>(input), len); 35 } 36 37 virtual void Finish(void* output, size_t len) OVERRIDE { 38 ScopedOpenSSLSafeSizeBuffer<SHA256_DIGEST_LENGTH> result( 39 static_cast<unsigned char*>(output), len); 40 SHA256_Final(result.safe_buffer(), &ctx_); 41 } 42 43 virtual bool Serialize(Pickle* pickle) OVERRIDE; 44 virtual bool Deserialize(PickleIterator* data_iterator) OVERRIDE; 45 46 private: 47 SHA256_CTX ctx_; 48 }; 49 50 bool SecureHashSHA256OpenSSL::Serialize(Pickle* pickle) { 51 if (!pickle) 52 return false; 53 54 if (!pickle->WriteInt(kSecureHashVersion) || 55 !pickle->WriteString(kSHA256Descriptor) || 56 !pickle->WriteBytes(&ctx_, sizeof(ctx_))) { 57 return false; 58 } 59 60 return true; 61 } 62 63 bool SecureHashSHA256OpenSSL::Deserialize(PickleIterator* data_iterator) { 64 if (!data_iterator) 65 return false; 66 67 int version; 68 if (!data_iterator->ReadInt(&version)) 69 return false; 70 71 if (version > kSecureHashVersion) 72 return false; // We don't know how to deal with this. 73 74 std::string type; 75 if (!data_iterator->ReadString(&type)) 76 return false; 77 78 if (type != kSHA256Descriptor) 79 return false; // It's the wrong kind. 80 81 const char* data = NULL; 82 if (!data_iterator->ReadBytes(&data, sizeof(ctx_))) 83 return false; 84 85 memcpy(&ctx_, data, sizeof(ctx_)); 86 87 return true; 88 } 89 90 } // namespace 91 92 SecureHash* SecureHash::Create(Algorithm algorithm) { 93 switch (algorithm) { 94 case SHA256: 95 return new SecureHashSHA256OpenSSL(); 96 default: 97 NOTIMPLEMENTED(); 98 return NULL; 99 } 100 } 101 102 } // namespace crypto 103