15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/crypto_export.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace crypto {
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GaloisHash implements the polynomial authenticator part of GCM as specified
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Specifically it implements the GHASH function, defined in section 2.3 of
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that document.
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In SP-800-38D, GHASH is defined differently and takes only a single data
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// argument. But it is always called with an argument of a certain form:
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   GHASH_H (A || 0^v || C || 0^u || [len(A)]_64 || [len(C)]_64)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This mirrors how the gcm-revised-spec.pdf version of GHASH handles its two
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// data arguments. The two GHASH functions therefore differ only in whether the
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// data is formatted inside or outside of the function.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WARNING: do not use this as a generic authenticator. Polynomial
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// authenticators must be used in the correct manner and any use outside of GCM
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// requires careful consideration.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WARNING: this code is not constant time. However, in all likelihood, nor is
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the implementation of AES that is used.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CRYPTO_EXPORT_PRIVATE GaloisHash {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit GaloisHash(const uint8 key[16]);
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset prepares to digest a fresh message with the same key. This is more
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // efficient than creating a fresh object.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Reset();
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UpdateAdditional hashes in `additional' data. This is data that is not
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // encrypted, but is covered by the authenticator. All additional data must
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be written before any ciphertext is written.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateAdditional(const uint8* data, size_t length);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UpdateCiphertext hashes in ciphertext to be authenticated.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateCiphertext(const uint8* data, size_t length);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finish completes the hash computation and writes at most |len| bytes of
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the result to |output|.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Finish(void* output, size_t len);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum State {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kHashingAdditionalData,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kHashingCiphertext,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kComplete,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct FieldElement {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint64 low, hi;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add returns |x|+|y|.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static FieldElement Add(const FieldElement& x, const FieldElement& y);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Double returns 2*|x|.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static FieldElement Double(const FieldElement& x);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MulAfterPrecomputation sets |x| = |x|*h where h is |table[1]| and
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // table[i] = i*h for i=0..15.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void MulAfterPrecomputation(const FieldElement* table,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     FieldElement* x);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Mul16 sets |x| = 16*|x|.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void Mul16(FieldElement* x);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UpdateBlocks processes |num_blocks| 16-bytes blocks from |bytes|.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateBlocks(const uint8* bytes, size_t num_blocks);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update processes |length| bytes from |bytes| and calls UpdateBlocks on as
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // much data as possible. It uses |buf_| to buffer any remaining data and
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // always consumes all of |bytes|.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Update(const uint8* bytes, size_t length);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FieldElement y_;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  State state_;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t additional_bytes_;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t ciphertext_bytes_;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint8 buf_[16];
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t buf_used_;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FieldElement product_table_[16];
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace crypto
87