Home | History | Annotate | Download | only in crypto
      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