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 "base/logging.h"
      8 #include "base/pickle.h"
      9 #include "crypto/third_party/nss/chromium-blapi.h"
     10 #include "crypto/third_party/nss/chromium-sha256.h"
     11 
     12 namespace crypto {
     13 
     14 namespace {
     15 
     16 const char kSHA256Descriptor[] = "NSS";
     17 
     18 class SecureHashSHA256NSS : public SecureHash {
     19  public:
     20   static const int kSecureHashVersion = 1;
     21 
     22   SecureHashSHA256NSS() {
     23     SHA256_Begin(&ctx_);
     24   }
     25 
     26   virtual ~SecureHashSHA256NSS() {
     27     memset(&ctx_, 0, sizeof(ctx_));
     28   }
     29 
     30   // SecureHash implementation:
     31   virtual void Update(const void* input, size_t len) OVERRIDE {
     32     SHA256_Update(&ctx_, static_cast<const unsigned char*>(input), len);
     33   }
     34 
     35   virtual void Finish(void* output, size_t len) OVERRIDE {
     36     SHA256_End(&ctx_, static_cast<unsigned char*>(output), NULL,
     37                static_cast<unsigned int>(len));
     38   }
     39 
     40   virtual bool Serialize(Pickle* pickle) OVERRIDE;
     41   virtual bool Deserialize(PickleIterator* data_iterator) OVERRIDE;
     42 
     43  private:
     44   SHA256Context ctx_;
     45 };
     46 
     47 bool SecureHashSHA256NSS::Serialize(Pickle* pickle) {
     48   if (!pickle)
     49     return false;
     50 
     51   if (!pickle->WriteInt(kSecureHashVersion) ||
     52       !pickle->WriteString(kSHA256Descriptor) ||
     53       !pickle->WriteBytes(&ctx_, sizeof(ctx_))) {
     54     return false;
     55   }
     56 
     57   return true;
     58 }
     59 
     60 bool SecureHashSHA256NSS::Deserialize(PickleIterator* data_iterator) {
     61   int version;
     62   if (!data_iterator->ReadInt(&version))
     63     return false;
     64 
     65   if (version > kSecureHashVersion)
     66     return false;  // We don't know how to deal with this.
     67 
     68   std::string type;
     69   if (!data_iterator->ReadString(&type))
     70     return false;
     71 
     72   if (type != kSHA256Descriptor)
     73     return false;  // It's the wrong kind.
     74 
     75   const char* data = NULL;
     76   if (!data_iterator->ReadBytes(&data, sizeof(ctx_)))
     77     return false;
     78 
     79   memcpy(&ctx_, data, sizeof(ctx_));
     80 
     81   return true;
     82 }
     83 
     84 }  // namespace
     85 
     86 SecureHash* SecureHash::Create(Algorithm algorithm) {
     87   switch (algorithm) {
     88     case SHA256:
     89       return new SecureHashSHA256NSS();
     90     default:
     91       NOTIMPLEMENTED();
     92       return NULL;
     93   }
     94 }
     95 
     96 }  // namespace crypto
     97