From 37d3d9e604f295078659dceb66ff31439378daf4 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 6 Jul 2024 08:50:51 -0400 Subject: [PATCH] removed openssl 1.0.2 support --- libi2pd/ChaCha20.cpp | 137 ----------------------- libi2pd/ChaCha20.h | 72 ------------ libi2pd/Crypto.cpp | 113 +------------------ libi2pd/Crypto.h | 101 ++--------------- libi2pd/Poly1305.cpp | 25 ----- libi2pd/Poly1305.h | 261 ------------------------------------------- 6 files changed, 8 insertions(+), 701 deletions(-) delete mode 100644 libi2pd/ChaCha20.cpp delete mode 100644 libi2pd/ChaCha20.h delete mode 100644 libi2pd/Poly1305.cpp delete mode 100644 libi2pd/Poly1305.h diff --git a/libi2pd/ChaCha20.cpp b/libi2pd/ChaCha20.cpp deleted file mode 100644 index 66bc135f..00000000 --- a/libi2pd/ChaCha20.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/* -* Copyright (c) 2013-2020, The PurpleI2P Project -* -* This file is part of Purple i2pd project and licensed under BSD3 -* -* See full license text in LICENSE file at top of project tree -* -* Kovri go write your own code -* -*/ - -#include "I2PEndian.h" -#include "ChaCha20.h" - -#if !OPENSSL_AEAD_CHACHA20_POLY1305 -namespace i2p -{ -namespace crypto -{ -namespace chacha -{ -void u32t8le(uint32_t v, uint8_t * p) -{ - p[0] = v & 0xff; - p[1] = (v >> 8) & 0xff; - p[2] = (v >> 16) & 0xff; - p[3] = (v >> 24) & 0xff; -} - -uint32_t u8t32le(const uint8_t * p) -{ - uint32_t value = p[3]; - - value = (value << 8) | p[2]; - value = (value << 8) | p[1]; - value = (value << 8) | p[0]; - - return value; -} - -uint32_t rotl32(uint32_t x, int n) -{ - return x << n | (x >> (-n & 31)); -} - -void quarterround(uint32_t *x, int a, int b, int c, int d) -{ - x[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 16); - x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 12); - x[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 8); - x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 7); -} - - -void Chacha20Block::operator << (const Chacha20State & st) -{ - int i; - for (i = 0; i < 16; i++) - u32t8le(st.data[i], data + (i << 2)); -} - -void block (Chacha20State &input, int rounds) -{ - int i; - Chacha20State x; - x.Copy(input); - - for (i = rounds; i > 0; i -= 2) - { - quarterround(x.data, 0, 4, 8, 12); - quarterround(x.data, 1, 5, 9, 13); - quarterround(x.data, 2, 6, 10, 14); - quarterround(x.data, 3, 7, 11, 15); - quarterround(x.data, 0, 5, 10, 15); - quarterround(x.data, 1, 6, 11, 12); - quarterround(x.data, 2, 7, 8, 13); - quarterround(x.data, 3, 4, 9, 14); - } - x += input; - input.block << x; -} - -void Chacha20Init (Chacha20State& state, const uint8_t * nonce, const uint8_t * key, uint32_t counter) -{ - state.data[0] = 0x61707865; - state.data[1] = 0x3320646e; - state.data[2] = 0x79622d32; - state.data[3] = 0x6b206574; - for (size_t i = 0; i < 8; i++) - state.data[4 + i] = chacha::u8t32le(key + i * 4); - - state.data[12] = htole32 (counter); - for (size_t i = 0; i < 3; i++) - state.data[13 + i] = chacha::u8t32le(nonce + i * 4); -} - -void Chacha20SetCounter (Chacha20State& state, uint32_t counter) -{ - state.data[12] = htole32 (counter); - state.offset = 0; -} - -void Chacha20Encrypt (Chacha20State& state, uint8_t * buf, size_t sz) -{ - if (state.offset > 0) - { - // previous block if any - auto s = chacha::blocksize - state.offset; - if (sz < s) s = sz; - for (size_t i = 0; i < s; i++) - buf[i] ^= state.block.data[state.offset + i]; - buf += s; - sz -= s; - state.offset += s; - if (state.offset >= chacha::blocksize) state.offset = 0; - } - for (size_t i = 0; i < sz; i += chacha::blocksize) - { - chacha::block(state, chacha::rounds); - state.data[12]++; - for (size_t j = i; j < i + chacha::blocksize; j++) - { - if (j >= sz) - { - state.offset = j & 0x3F; // % 64 - break; - } - buf[j] ^= state.block.data[j - i]; - } - } -} - -} // namespace chacha -} // namespace crypto -} // namespace i2p - -#endif diff --git a/libi2pd/ChaCha20.h b/libi2pd/ChaCha20.h deleted file mode 100644 index 4364024b..00000000 --- a/libi2pd/ChaCha20.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -* Copyright (c) 2013-2020, The PurpleI2P Project -* -* This file is part of Purple i2pd project and licensed under BSD3 -* -* See full license text in LICENSE file at top of project tree -* -* Kovri go write your own code -* -*/ -#ifndef LIBI2PD_CHACHA20_H -#define LIBI2PD_CHACHA20_H -#include -#include -#include -#include -#include "Crypto.h" - -#if !OPENSSL_AEAD_CHACHA20_POLY1305 -namespace i2p -{ -namespace crypto -{ - const std::size_t CHACHA20_KEY_BYTES = 32; - const std::size_t CHACHA20_NOUNCE_BYTES = 12; - -namespace chacha -{ - constexpr std::size_t blocksize = 64; - constexpr int rounds = 20; - - struct Chacha20State; - struct Chacha20Block - { - Chacha20Block () {}; - Chacha20Block (Chacha20Block &&) = delete; - - uint8_t data[blocksize]; - - void operator << (const Chacha20State & st); - }; - - struct Chacha20State - { - Chacha20State (): offset (0) {}; - Chacha20State (Chacha20State &&) = delete; - - Chacha20State & operator += (const Chacha20State & other) - { - for(int i = 0; i < 16; i++) - data[i] += other.data[i]; - return *this; - } - - void Copy(const Chacha20State & other) - { - memcpy(data, other.data, sizeof(uint32_t) * 16); - } - uint32_t data[16]; - Chacha20Block block; - size_t offset; - }; - - void Chacha20Init (Chacha20State& state, const uint8_t * nonce, const uint8_t * key, uint32_t counter); - void Chacha20SetCounter (Chacha20State& state, uint32_t counter); - void Chacha20Encrypt (Chacha20State& state, uint8_t * buf, size_t sz); // encrypt buf in place -} // namespace chacha -} // namespace crypto -} // namespace i2p - -#endif -#endif diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 3e5bdd35..960c400c 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -19,16 +19,11 @@ #if OPENSSL_HKDF #include #endif -#if !OPENSSL_AEAD_CHACHA20_POLY1305 -#include "ChaCha20.h" -#include "Poly1305.h" -#endif #include "Crypto.h" #include "Ed25519.h" #include "I2PEndian.h" #include "Log.h" - namespace i2p { namespace crypto @@ -988,7 +983,6 @@ namespace crypto if (len < msgLen) return false; if (encrypt && len < msgLen + 16) return false; bool ret = true; -#if OPENSSL_AEAD_CHACHA20_POLY1305 int outlen = 0; EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new (); if (encrypt) @@ -1013,73 +1007,12 @@ namespace crypto } EVP_CIPHER_CTX_free (ctx); -#else - chacha::Chacha20State state; - // generate one time poly key - chacha::Chacha20Init (state, nonce, key, 0); - uint64_t polyKey[8]; - memset(polyKey, 0, sizeof(polyKey)); - chacha::Chacha20Encrypt (state, (uint8_t *)polyKey, 64); - // create Poly1305 hash - Poly1305 polyHash (polyKey); - if (!ad) adLen = 0; - uint8_t padding[16]; memset (padding, 0, 16); - if (ad) - { - polyHash.Update (ad, adLen);// additional authenticated data - auto rem = adLen & 0x0F; // %16 - if (rem) - { - // padding1 - rem = 16 - rem; - polyHash.Update (padding, rem); - } - } - // encrypt/decrypt data and add to hash - Chacha20SetCounter (state, 1); - if (buf != msg) - memcpy (buf, msg, msgLen); - if (encrypt) - { - chacha::Chacha20Encrypt (state, buf, msgLen); // encrypt - polyHash.Update (buf, msgLen); // after encryption - } - else - { - polyHash.Update (buf, msgLen); // before decryption - chacha::Chacha20Encrypt (state, buf, msgLen); // decrypt - } - - auto rem = msgLen & 0x0F; // %16 - if (rem) - { - // padding2 - rem = 16 - rem; - polyHash.Update (padding, rem); - } - // adLen and msgLen - htole64buf (padding, adLen); - htole64buf (padding + 8, msgLen); - polyHash.Update (padding, 16); - - if (encrypt) - // calculate Poly1305 tag and write in after encrypted data - polyHash.Finish ((uint64_t *)(buf + msgLen)); - else - { - uint64_t tag[4]; - // calculate Poly1305 tag - polyHash.Finish (tag); - if (memcmp (tag, msg + msgLen, 16)) ret = false; // compare with provided - } -#endif return ret; } void AEADChaCha20Poly1305Encrypt (const std::vector >& bufs, const uint8_t * key, const uint8_t * nonce, uint8_t * mac) { if (bufs.empty ()) return; -#if OPENSSL_AEAD_CHACHA20_POLY1305 int outlen = 0; EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new (); EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), 0, 0, 0); @@ -1090,45 +1023,10 @@ namespace crypto EVP_EncryptFinal_ex(ctx, NULL, &outlen); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, mac); EVP_CIPHER_CTX_free (ctx); -#else - chacha::Chacha20State state; - // generate one time poly key - chacha::Chacha20Init (state, nonce, key, 0); - uint64_t polyKey[8]; - memset(polyKey, 0, sizeof(polyKey)); - chacha::Chacha20Encrypt (state, (uint8_t *)polyKey, 64); - Poly1305 polyHash (polyKey); - // encrypt buffers - Chacha20SetCounter (state, 1); - size_t size = 0; - for (const auto& it: bufs) - { - chacha::Chacha20Encrypt (state, it.first, it.second); - polyHash.Update (it.first, it.second); // after encryption - size += it.second; - } - // padding - uint8_t padding[16]; - memset (padding, 0, 16); - auto rem = size & 0x0F; // %16 - if (rem) - { - // padding2 - rem = 16 - rem; - polyHash.Update (padding, rem); - } - // adLen and msgLen - // adLen is always zero - htole64buf (padding + 8, size); - polyHash.Update (padding, 16); - // MAC - polyHash.Finish ((uint64_t *)mac); -#endif } void ChaCha20 (const uint8_t * msg, size_t msgLen, const uint8_t * key, const uint8_t * nonce, uint8_t * out) { -#if OPENSSL_AEAD_CHACHA20_POLY1305 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new (); uint32_t iv[4]; iv[0] = htole32 (1); memcpy (iv + 1, nonce, 12); // counter | nonce @@ -1137,12 +1035,6 @@ namespace crypto EVP_EncryptUpdate(ctx, out, &outlen, msg, msgLen); EVP_EncryptFinal_ex(ctx, NULL, &outlen); EVP_CIPHER_CTX_free (ctx); -#else - chacha::Chacha20State state; - chacha::Chacha20Init (state, nonce, key, 1); - if (out != msg) memcpy (out, msg, msgLen); - chacha::Chacha20Encrypt (state, out, msgLen); -#endif } void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, @@ -1295,9 +1187,6 @@ namespace crypto void InitCrypto (bool precomputation, bool aesni, bool force) { i2p::cpu::Detect (aesni, force); -#if LEGACY_OPENSSL - SSL_library_init (); -#endif /* auto numLocks = CRYPTO_num_locks(); for (int i = 0; i < numLocks; i++) m_OpenSSLMutexes.emplace_back (new std::mutex); diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 816d79fd..5c1bd20d 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -29,24 +29,12 @@ #include "CPU.h" // recognize openssl version and features -#if (defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER >= 0x3050200fL)) // LibreSSL 3.5.2 and above -# define LEGACY_OPENSSL 0 -#elif ((OPENSSL_VERSION_NUMBER < 0x010100000) || defined(LIBRESSL_VERSION_NUMBER)) // 1.0.2 and below or LibreSSL -# define LEGACY_OPENSSL 1 -# define X509_getm_notBefore X509_get_notBefore -# define X509_getm_notAfter X509_get_notAfter -#else -# define LEGACY_OPENSSL 0 -# if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1 -# define OPENSSL_HKDF 1 -# define OPENSSL_EDDSA 1 -# define OPENSSL_X25519 1 -# if (OPENSSL_VERSION_NUMBER != 0x030000000) // 3.0.0, regression in SipHash -# define OPENSSL_SIPHASH 1 -# endif -# endif -# if !defined OPENSSL_NO_CHACHA && !defined OPENSSL_NO_POLY1305 // some builds might not include them -# define OPENSSL_AEAD_CHACHA20_POLY1305 1 +#if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1 +# define OPENSSL_HKDF 1 +# define OPENSSL_EDDSA 1 +# define OPENSSL_X25519 1 +# if (OPENSSL_VERSION_NUMBER != 0x030000000) // 3.0.0, regression in SipHash +# define OPENSSL_SIPHASH 1 # endif #endif @@ -312,79 +300,4 @@ namespace crypto } } -// take care about openssl below 1.1.0 -#if LEGACY_OPENSSL -// define getters and setters introduced in 1.1.0 -inline int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) - { - if (d->p) BN_free (d->p); - if (d->q) BN_free (d->q); - if (d->g) BN_free (d->g); - d->p = p; d->q = q; d->g = g; return 1; - } -inline int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) - { - if (d->pub_key) BN_free (d->pub_key); - if (d->priv_key) BN_free (d->priv_key); - d->pub_key = pub_key; d->priv_key = priv_key; return 1; - } -inline void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key) - { *pub_key = d->pub_key; *priv_key = d->priv_key; } -inline int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) - { - if (sig->r) BN_free (sig->r); - if (sig->s) BN_free (sig->s); - sig->r = r; sig->s = s; return 1; - } -inline void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) - { *pr = sig->r; *ps = sig->s; } - -inline int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) - { - if (sig->r) BN_free (sig->r); - if (sig->s) BN_free (sig->s); - sig->r = r; sig->s = s; return 1; - } -inline void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) - { *pr = sig->r; *ps = sig->s; } - -inline int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) - { - if (r->n) BN_free (r->n); - if (r->e) BN_free (r->e); - if (r->d) BN_free (r->d); - r->n = n; r->e = e; r->d = d; return 1; - } -inline void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) - { *n = r->n; *e = r->e; *d = r->d; } - -inline int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) - { - if (dh->p) BN_free (dh->p); - if (dh->q) BN_free (dh->q); - if (dh->g) BN_free (dh->g); - dh->p = p; dh->q = q; dh->g = g; return 1; - } -inline int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) - { - if (dh->pub_key) BN_free (dh->pub_key); - if (dh->priv_key) BN_free (dh->priv_key); - dh->pub_key = pub_key; dh->priv_key = priv_key; return 1; - } -inline void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) - { *pub_key = dh->pub_key; *priv_key = dh->priv_key; } - -inline RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) - { return pkey->pkey.rsa; } - -inline EVP_MD_CTX *EVP_MD_CTX_new () - { return EVP_MD_CTX_create(); } -inline void EVP_MD_CTX_free (EVP_MD_CTX *ctx) - { EVP_MD_CTX_destroy (ctx); } - -// ssl -#define TLS_method TLSv1_method - -#endif - #endif diff --git a/libi2pd/Poly1305.cpp b/libi2pd/Poly1305.cpp deleted file mode 100644 index 20b3ab2a..00000000 --- a/libi2pd/Poly1305.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/** - * This code is licensed under the MCGSI Public License - * Copyright 2018 Jeff Becker - * - *Kovri go write your own code - * - */ - -#include "Poly1305.h" - -#if !OPENSSL_AEAD_CHACHA20_POLY1305 -namespace i2p -{ -namespace crypto -{ - void Poly1305HMAC(uint64_t * out, const uint64_t * key, const uint8_t * buf, std::size_t sz) - { - Poly1305 p(key); - p.Update(buf, sz); - p.Finish(out); - } -} -} -#endif - diff --git a/libi2pd/Poly1305.h b/libi2pd/Poly1305.h deleted file mode 100644 index db659b84..00000000 --- a/libi2pd/Poly1305.h +++ /dev/null @@ -1,261 +0,0 @@ -/** - * This code is licensed under the MCGSI Public License - * Copyright 2018 Jeff Becker - * - * Kovri go write your own code - * - */ - -#ifndef LIBI2PD_POLY1305_H -#define LIBI2PD_POLY1305_H -#include -#include -#include "Crypto.h" - -#if !OPENSSL_AEAD_CHACHA20_POLY1305 -namespace i2p -{ -namespace crypto -{ - const std::size_t POLY1305_DIGEST_BYTES = 16; - const std::size_t POLY1305_DIGEST_DWORDS = 4; - const std::size_t POLY1305_KEY_BYTES = 32; - const std::size_t POLY1305_KEY_DWORDS = 8; - const std::size_t POLY1305_BLOCK_BYTES = 16; - - namespace poly1305 - { - struct LongBlock - { - unsigned long data[17]; - operator unsigned long * () - { - return data; - } - }; - - struct Block - { - unsigned char data[17]; - - void Zero() - { - memset(data, 0, sizeof(data)); - } - - operator uint8_t * () - { - return data; - } - - Block & operator += (const Block & other) - { - unsigned short u; - unsigned int i; - for(u = 0, i = 0; i < 17; i++) - { - u += (unsigned short) data[i] + (unsigned short) other.data[i]; - data[i] = (unsigned char) u & 0xff; - u >>= 8; - } - return *this; - } - - Block & operator %=(const LongBlock & other) - { - unsigned long u; - unsigned int i; - u = 0; - for (i = 0; i < 16; i++) { - u += other.data[i]; - data[i] = (unsigned char)u & 0xff; - u >>= 8; - } - u += other.data[16]; - data[16] = (unsigned char)u & 0x03; - u >>= 2; - u += (u << 2); - for (i = 0; i < 16; i++) { - u += data[i]; - data[i] = (unsigned char)u & 0xff; - u >>= 8; - } - data[16] += (unsigned char)u; - return *this; - } - - Block & operator = (const Block & other) - { - memcpy(data, other.data, sizeof(data)); - return *this; - } - - Block & operator ~ () - { - static const Block minusp = { - 0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xfc - }; - Block orig; - unsigned char neg; - unsigned int i; - orig = *this; - *this += minusp; - neg = -(data[16] >> 7); - for(i = 0; i < 17; i++) - data[i] ^= neg & (orig.data[i] ^ data[i]); - - return *this; - } - - void PutKey(const uint64_t * key_l) - { - const uint8_t * key = (const uint8_t*) key_l; - data[0] = key[0] & 0xff; - data[1] = key[1] & 0xff; - data[2] = key[2] & 0xff; - data[3] = key[3] & 0x0f; - data[4] = key[4] & 0xfc; - data[5] = key[5] & 0xff; - data[6] = key[6] & 0xff; - data[7] = key[7] & 0x0f; - data[8] = key[8] & 0xfc; - data[9] = key[9] & 0xff; - data[10] = key[10] & 0xff; - data[11] = key[11] & 0x0f; - data[12] = key[12] & 0xfc; - data[13] = key[13] & 0xff; - data[14] = key[14] & 0xff; - data[15] = key[15] & 0x0f; - data[16] = 0; - } - - template - void Put(const Int_t * d, uint8_t last=0) - { - memcpy(data, d, 16); - data[16] = last; - } - }; - - struct Buffer - { - uint8_t data[POLY1305_BLOCK_BYTES]; - - operator uint8_t * () - { - return data; - } - }; - } - - struct Poly1305 - { - Poly1305(const uint64_t * key) - { - m_Leftover = 0; - m_H.Zero(); - m_Final = 0; - m_R.PutKey(key); - m_Pad.Put(key + 2); - } - - void Update(const uint8_t * buf, size_t sz) - { - // process leftover - if(m_Leftover) - { - size_t want = POLY1305_BLOCK_BYTES - m_Leftover; - if(want > sz) want = sz; - memcpy(m_Buffer + m_Leftover, buf, want); - sz -= want; - buf += want; - m_Leftover += want; - if(m_Leftover < POLY1305_BLOCK_BYTES) return; - Blocks(m_Buffer, POLY1305_BLOCK_BYTES); - m_Leftover = 0; - } - // process blocks - if(sz >= POLY1305_BLOCK_BYTES) - { - size_t want = (sz & ~(POLY1305_BLOCK_BYTES - 1)); - Blocks(buf, want); - buf += want; - sz -= want; - } - // leftover - if(sz) - { - memcpy(m_Buffer+m_Leftover, buf, sz); - m_Leftover += sz; - } - } - - void Blocks(const uint8_t * buf, size_t sz) - { - const unsigned char hi = m_Final ^ 1; - while (sz >= POLY1305_BLOCK_BYTES) { - unsigned long u; - unsigned int i, j; - m_Msg.Put(buf, hi); - /* h += m */ - m_H += m_Msg; - - /* h *= r */ - for (i = 0; i < 17; i++) { - u = 0; - for (j = 0; j <= i ; j++) { - u += (unsigned short)m_H.data[j] * m_R.data[i - j]; - } - for (j = i + 1; j < 17; j++) { - unsigned long v = (unsigned short)m_H.data[j] * m_R.data[i + 17 - j]; - v = ((v << 8) + (v << 6)); /* v *= (5 << 6); */ - u += v; - } - m_HR[i] = u; - } - /* (partial) h %= p */ - m_H %= m_HR; - buf += POLY1305_BLOCK_BYTES; - sz -= POLY1305_BLOCK_BYTES; - } - } - - void Finish(uint64_t * out) - { - // process leftovers - if(m_Leftover) - { - size_t idx = m_Leftover; - m_Buffer[idx++] = 1; - for(; idx < POLY1305_BLOCK_BYTES; idx++) - m_Buffer[idx] = 0; - m_Final = 1; - Blocks(m_Buffer, POLY1305_BLOCK_BYTES); - } - - // freeze H - ~m_H; - // add pad - m_H += m_Pad; - // copy digest - memcpy(out, m_H, 16); - } - - size_t m_Leftover; - poly1305::Buffer m_Buffer; - poly1305::Block m_H; - poly1305::Block m_R; - poly1305::Block m_Pad; - poly1305::Block m_Msg; - poly1305::LongBlock m_HR; - uint8_t m_Final; - }; - - void Poly1305HMAC(uint64_t * out, const uint64_t * key, const uint8_t * buf, std::size_t sz); -} -} -#endif - -#endif