mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-10 00:00:29 +03:00
removed openssl 1.0.2 support
This commit is contained in:
parent
d23451fdf6
commit
37d3d9e604
@ -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
|
|
@ -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 <cstdint>
|
|
||||||
#include <cstring>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <string.h>
|
|
||||||
#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
|
|
@ -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
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@ -19,16 +19,11 @@
|
|||||||
#if OPENSSL_HKDF
|
#if OPENSSL_HKDF
|
||||||
#include <openssl/kdf.h>
|
#include <openssl/kdf.h>
|
||||||
#endif
|
#endif
|
||||||
#if !OPENSSL_AEAD_CHACHA20_POLY1305
|
|
||||||
#include "ChaCha20.h"
|
|
||||||
#include "Poly1305.h"
|
|
||||||
#endif
|
|
||||||
#include "Crypto.h"
|
#include "Crypto.h"
|
||||||
#include "Ed25519.h"
|
#include "Ed25519.h"
|
||||||
#include "I2PEndian.h"
|
#include "I2PEndian.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace crypto
|
namespace crypto
|
||||||
@ -988,7 +983,6 @@ namespace crypto
|
|||||||
if (len < msgLen) return false;
|
if (len < msgLen) return false;
|
||||||
if (encrypt && len < msgLen + 16) return false;
|
if (encrypt && len < msgLen + 16) return false;
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
#if OPENSSL_AEAD_CHACHA20_POLY1305
|
|
||||||
int outlen = 0;
|
int outlen = 0;
|
||||||
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new ();
|
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new ();
|
||||||
if (encrypt)
|
if (encrypt)
|
||||||
@ -1013,73 +1007,12 @@ namespace crypto
|
|||||||
}
|
}
|
||||||
|
|
||||||
EVP_CIPHER_CTX_free (ctx);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AEADChaCha20Poly1305Encrypt (const std::vector<std::pair<uint8_t *, size_t> >& bufs, const uint8_t * key, const uint8_t * nonce, uint8_t * mac)
|
void AEADChaCha20Poly1305Encrypt (const std::vector<std::pair<uint8_t *, size_t> >& bufs, const uint8_t * key, const uint8_t * nonce, uint8_t * mac)
|
||||||
{
|
{
|
||||||
if (bufs.empty ()) return;
|
if (bufs.empty ()) return;
|
||||||
#if OPENSSL_AEAD_CHACHA20_POLY1305
|
|
||||||
int outlen = 0;
|
int outlen = 0;
|
||||||
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new ();
|
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new ();
|
||||||
EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), 0, 0, 0);
|
EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), 0, 0, 0);
|
||||||
@ -1090,45 +1023,10 @@ namespace crypto
|
|||||||
EVP_EncryptFinal_ex(ctx, NULL, &outlen);
|
EVP_EncryptFinal_ex(ctx, NULL, &outlen);
|
||||||
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, mac);
|
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, mac);
|
||||||
EVP_CIPHER_CTX_free (ctx);
|
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)
|
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 ();
|
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new ();
|
||||||
uint32_t iv[4];
|
uint32_t iv[4];
|
||||||
iv[0] = htole32 (1); memcpy (iv + 1, nonce, 12); // counter | nonce
|
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_EncryptUpdate(ctx, out, &outlen, msg, msgLen);
|
||||||
EVP_EncryptFinal_ex(ctx, NULL, &outlen);
|
EVP_EncryptFinal_ex(ctx, NULL, &outlen);
|
||||||
EVP_CIPHER_CTX_free (ctx);
|
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,
|
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)
|
void InitCrypto (bool precomputation, bool aesni, bool force)
|
||||||
{
|
{
|
||||||
i2p::cpu::Detect (aesni, force);
|
i2p::cpu::Detect (aesni, force);
|
||||||
#if LEGACY_OPENSSL
|
|
||||||
SSL_library_init ();
|
|
||||||
#endif
|
|
||||||
/* auto numLocks = CRYPTO_num_locks();
|
/* auto numLocks = CRYPTO_num_locks();
|
||||||
for (int i = 0; i < numLocks; i++)
|
for (int i = 0; i < numLocks; i++)
|
||||||
m_OpenSSLMutexes.emplace_back (new std::mutex);
|
m_OpenSSLMutexes.emplace_back (new std::mutex);
|
||||||
|
@ -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
|
* This file is part of Purple i2pd project and licensed under BSD3
|
||||||
*
|
*
|
||||||
@ -29,14 +29,6 @@
|
|||||||
#include "CPU.h"
|
#include "CPU.h"
|
||||||
|
|
||||||
// recognize openssl version and features
|
// 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
|
#if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1
|
||||||
# define OPENSSL_HKDF 1
|
# define OPENSSL_HKDF 1
|
||||||
# define OPENSSL_EDDSA 1
|
# define OPENSSL_EDDSA 1
|
||||||
@ -45,10 +37,6 @@
|
|||||||
# define OPENSSL_SIPHASH 1
|
# define OPENSSL_SIPHASH 1
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
# if !defined OPENSSL_NO_CHACHA && !defined OPENSSL_NO_POLY1305 // some builds might not include them
|
|
||||||
# define OPENSSL_AEAD_CHACHA20_POLY1305 1
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
@ -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
|
#endif
|
||||||
|
@ -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
|
|
||||||
|
|
@ -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 <cstdint>
|
|
||||||
#include <cstring>
|
|
||||||
#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<typename Int_t>
|
|
||||||
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
|
|
Loading…
Reference in New Issue
Block a user