Remove unused ECIES routines

This commit is contained in:
Nik Bougalis
2016-04-30 13:47:30 -07:00
committed by Howard Hinnant
parent f081e80c28
commit 3d063edb72
5 changed files with 0 additions and 352 deletions

View File

@@ -2081,8 +2081,6 @@
</ClInclude>
<ClInclude Include="..\..\src\ripple\crypto\csprng.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\crypto\ECIES.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\crypto\GenerateDeterministicKey.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\crypto\impl\csprng.cpp">
@@ -2095,10 +2093,6 @@
</ClCompile>
<ClInclude Include="..\..\src\ripple\crypto\impl\ECDSAKey.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\crypto\impl\ECIES.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\crypto\impl\ec_key.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>

View File

@@ -2607,9 +2607,6 @@
<ClInclude Include="..\..\src\ripple\crypto\csprng.h">
<Filter>ripple\crypto</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\crypto\ECIES.h">
<Filter>ripple\crypto</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\crypto\GenerateDeterministicKey.h">
<Filter>ripple\crypto</Filter>
</ClInclude>
@@ -2622,9 +2619,6 @@
<ClInclude Include="..\..\src\ripple\crypto\impl\ECDSAKey.h">
<Filter>ripple\crypto\impl</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\crypto\impl\ECIES.cpp">
<Filter>ripple\crypto\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\crypto\impl\ec_key.cpp">
<Filter>ripple\crypto\impl</Filter>
</ClCompile>

View File

@@ -1,37 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2014 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_CRYPTO_ECIES_H_INCLUDED
#define RIPPLE_CRYPTO_ECIES_H_INCLUDED
#include <ripple/basics/base_uint.h>
#include <ripple/basics/Blob.h>
namespace ripple {
// ECIES functions. These throw on failure
// encrypt/decrypt functions with integrity checking.
// Note that the other side must somehow know what keys to use
Blob encryptECIES (uint256 const& secretKey, Blob const& publicKey, Blob const& plaintext);
Blob decryptECIES (uint256 const& secretKey, Blob const& publicKey, Blob const& ciphertext);
} // ripple
#endif

View File

@@ -1,302 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <BeastConfig.h>
#include <ripple/basics/contract.h>
#include <ripple/crypto/ECIES.h>
#include <ripple/crypto/impl/ec_key.h>
#include <ripple/crypto/impl/ECDSAKey.h>
#include <ripple/crypto/csprng.h>
#include <ripple/beast/utility/rngfill.h>
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/hmac.h>
#include <openssl/pem.h>
namespace ripple {
// ECIES uses elliptic curve keys to send an encrypted message.
// A shared secret is generated from one public key and one private key.
// The same key results regardless of which key is public and which private.
// Anonymous messages can be sent by generating an ephemeral public/private
// key pair, using that private key with the recipient's public key to
// encrypt and publishing the ephemeral public key. Non-anonymous messages
// can be sent by using your own private key with the recipient's public key.
// A random IV is used to encrypt the message and an HMAC is used to ensure
// message integrity. If you need timestamps or need to tell the recipient
// which key to use (his, yours, or ephemeral) you must add that data.
// (Obviously, key information can't go in the encrypted portion anyway.)
// Our ciphertext is all encrypted except the IV. The encrypted data decodes as follows:
// 1) IV (unencrypted)
// 2) Encrypted: HMAC of original plaintext
// 3) Encrypted: Original plaintext
// 4) Encrypted: Rest of block/padding
// ECIES operations throw on any error such as a corrupt message or incorrect
// key. They *must* be called in try/catch blocks.
// Algorithmic choices:
#define ECIES_KEY_HASH SHA512 // Hash used to expand shared secret
#define ECIES_KEY_LENGTH (512/8) // Size of expanded shared secret
#define ECIES_MIN_SEC (128/8) // The minimum equivalent security
#define ECIES_ENC_ALGO EVP_aes_256_cbc() // Encryption algorithm
#define ECIES_ENC_KEY_TYPE uint256 // Type used to hold shared secret
#define ECIES_ENC_KEY_SIZE (256/8) // Encryption key size
#define ECIES_ENC_BLK_SIZE (128/8) // Encryption block size
#define ECIES_ENC_IV_TYPE uint128 // Type used to hold IV
#define ECIES_HMAC_ALGO EVP_sha256() // HMAC algorithm
#define ECIES_HMAC_KEY_TYPE uint256 // Type used to hold HMAC key
#define ECIES_HMAC_KEY_SIZE (256/8) // Size of HMAC key
#define ECIES_HMAC_TYPE uint256 // Type used to hold HMAC value
#define ECIES_HMAC_SIZE (256/8) // Size of HMAC value
// returns a 32-byte secret unique to these two keys. At least one private key must be known.
static void getECIESSecret (const openssl::ec_key& secretKey, const openssl::ec_key& publicKey, ECIES_ENC_KEY_TYPE& enc_key, ECIES_HMAC_KEY_TYPE& hmac_key)
{
EC_KEY* privkey = (EC_KEY*) secretKey.get();
EC_KEY* pubkey = (EC_KEY*) publicKey.get();
// Retrieve a secret generated from an EC key pair. At least one private key must be known.
if (privkey == nullptr || pubkey == nullptr)
Throw<std::runtime_error> ("missing key");
if (! EC_KEY_get0_private_key (privkey))
Throw<std::runtime_error> ("not a private key");
unsigned char rawbuf[512];
int buflen = ECDH_compute_key (rawbuf, 512, EC_KEY_get0_public_key (pubkey), privkey, nullptr);
if (buflen < ECIES_MIN_SEC)
Throw<std::runtime_error> ("ecdh key failed");
unsigned char hbuf[ECIES_KEY_LENGTH];
ECIES_KEY_HASH (rawbuf, buflen, hbuf);
memset (rawbuf, 0, ECIES_HMAC_KEY_SIZE);
assert ((ECIES_ENC_KEY_SIZE + ECIES_HMAC_KEY_SIZE) >= ECIES_KEY_LENGTH);
memcpy (enc_key.begin (), hbuf, ECIES_ENC_KEY_SIZE);
memcpy (hmac_key.begin (), hbuf + ECIES_ENC_KEY_SIZE, ECIES_HMAC_KEY_SIZE);
memset (hbuf, 0, ECIES_KEY_LENGTH);
}
static void getECIESSecret (uint256 const& secretKey,
Blob const& publicKey,
ECIES_ENC_KEY_TYPE& enc_key,
ECIES_HMAC_KEY_TYPE& hmac_key)
{
getECIESSecret (ECDSAPrivateKey (secretKey), ECDSAPublicKey (publicKey), enc_key, hmac_key);
}
static ECIES_HMAC_TYPE makeHMAC (const ECIES_HMAC_KEY_TYPE& secret, Blob const& data)
{
HMAC_CTX ctx;
HMAC_CTX_init (&ctx);
if (HMAC_Init_ex (&ctx, secret.begin (), ECIES_HMAC_KEY_SIZE, ECIES_HMAC_ALGO, nullptr) != 1)
{
HMAC_CTX_cleanup (&ctx);
Throw<std::runtime_error> ("init hmac");
}
if (HMAC_Update (&ctx, & (data.front ()), data.size ()) != 1)
{
HMAC_CTX_cleanup (&ctx);
Throw<std::runtime_error> ("update hmac");
}
ECIES_HMAC_TYPE ret;
unsigned int ml = ECIES_HMAC_SIZE;
if (HMAC_Final (&ctx, ret.begin (), &ml) != 1)
{
HMAC_CTX_cleanup (&ctx);
Throw<std::runtime_error> ("finalize hmac");
}
assert (ml == ECIES_HMAC_SIZE);
HMAC_CTX_cleanup (&ctx);
return ret;
}
Blob encryptECIES (uint256 const& secretKey, Blob const& publicKey, Blob const& plaintext)
{
ECIES_ENC_IV_TYPE iv;
beast::rngfill (
iv.begin (),
ECIES_ENC_BLK_SIZE,
crypto_prng());
ECIES_ENC_KEY_TYPE secret;
ECIES_HMAC_KEY_TYPE hmacKey;
getECIESSecret (secretKey, publicKey, secret, hmacKey);
ECIES_HMAC_TYPE hmac = makeHMAC (hmacKey, plaintext);
hmacKey.zero ();
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init (&ctx);
if (EVP_EncryptInit_ex (&ctx, ECIES_ENC_ALGO, nullptr, secret.begin (), iv.begin ()) != 1)
{
EVP_CIPHER_CTX_cleanup (&ctx);
secret.zero ();
Throw<std::runtime_error> ("init cipher ctx");
}
secret.zero ();
Blob out (plaintext.size () + ECIES_HMAC_SIZE + ECIES_ENC_KEY_SIZE + ECIES_ENC_BLK_SIZE, 0);
int len = 0, bytesWritten;
// output IV
memcpy (& (out.front ()), iv.begin (), ECIES_ENC_BLK_SIZE);
len = ECIES_ENC_BLK_SIZE;
// Encrypt/output HMAC
bytesWritten = out.capacity () - len;
assert (bytesWritten > 0);
if (EVP_EncryptUpdate (&ctx, & (out.front ()) + len, &bytesWritten, hmac.begin (), ECIES_HMAC_SIZE) < 0)
{
EVP_CIPHER_CTX_cleanup (&ctx);
Throw<std::runtime_error> ("");
}
len += bytesWritten;
// encrypt/output plaintext
bytesWritten = out.capacity () - len;
assert (bytesWritten > 0);
if (EVP_EncryptUpdate (&ctx, & (out.front ()) + len, &bytesWritten, & (plaintext.front ()), plaintext.size ()) < 0)
{
EVP_CIPHER_CTX_cleanup (&ctx);
Throw<std::runtime_error> ("");
}
len += bytesWritten;
// finalize
bytesWritten = out.capacity () - len;
if (EVP_EncryptFinal_ex (&ctx, & (out.front ()) + len, &bytesWritten) < 0)
{
EVP_CIPHER_CTX_cleanup (&ctx);
Throw<std::runtime_error> ("encryption error");
}
len += bytesWritten;
// Output contains: IV, encrypted HMAC, encrypted data, encrypted padding
assert (len <= (plaintext.size () + ECIES_HMAC_SIZE + (2 * ECIES_ENC_BLK_SIZE)));
assert (len >= (plaintext.size () + ECIES_HMAC_SIZE + ECIES_ENC_BLK_SIZE)); // IV, HMAC, data
out.resize (len);
EVP_CIPHER_CTX_cleanup (&ctx);
return out;
}
Blob decryptECIES (uint256 const& secretKey, Blob const& publicKey, Blob const& ciphertext)
{
// minimum ciphertext = IV + HMAC + 1 block
if (ciphertext.size () < ((2 * ECIES_ENC_BLK_SIZE) + ECIES_HMAC_SIZE) )
Throw<std::runtime_error> ("ciphertext too short");
// extract IV
ECIES_ENC_IV_TYPE iv;
memcpy (iv.begin (), & (ciphertext.front ()), ECIES_ENC_BLK_SIZE);
// begin decrypting
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init (&ctx);
ECIES_ENC_KEY_TYPE secret;
ECIES_HMAC_KEY_TYPE hmacKey;
getECIESSecret (secretKey, publicKey, secret, hmacKey);
if (EVP_DecryptInit_ex (&ctx, ECIES_ENC_ALGO, nullptr, secret.begin (), iv.begin ()) != 1)
{
secret.zero ();
hmacKey.zero ();
EVP_CIPHER_CTX_cleanup (&ctx);
Throw<std::runtime_error> ("unable to init cipher");
}
// decrypt mac
ECIES_HMAC_TYPE hmac;
int outlen = ECIES_HMAC_SIZE;
if ( (EVP_DecryptUpdate (&ctx, hmac.begin (), &outlen,
& (ciphertext.front ()) + ECIES_ENC_BLK_SIZE, ECIES_HMAC_SIZE + 1) != 1) || (outlen != ECIES_HMAC_SIZE) )
{
secret.zero ();
hmacKey.zero ();
EVP_CIPHER_CTX_cleanup (&ctx);
Throw<std::runtime_error> ("unable to extract hmac");
}
// decrypt plaintext (after IV and encrypted mac)
Blob plaintext (ciphertext.size () - ECIES_HMAC_SIZE - ECIES_ENC_BLK_SIZE);
outlen = plaintext.size ();
if (EVP_DecryptUpdate (&ctx, & (plaintext.front ()), &outlen,
& (ciphertext.front ()) + ECIES_ENC_BLK_SIZE + ECIES_HMAC_SIZE + 1,
ciphertext.size () - ECIES_ENC_BLK_SIZE - ECIES_HMAC_SIZE - 1) != 1)
{
secret.zero ();
hmacKey.zero ();
EVP_CIPHER_CTX_cleanup (&ctx);
Throw<std::runtime_error> ("unable to extract plaintext");
}
// decrypt padding
int flen = 0;
if (EVP_DecryptFinal (&ctx, & (plaintext.front ()) + outlen, &flen) != 1)
{
secret.zero ();
hmacKey.zero ();
EVP_CIPHER_CTX_cleanup (&ctx);
Throw<std::runtime_error> ("plaintext had bad padding");
}
plaintext.resize (flen + outlen);
// verify integrity
if (hmac != makeHMAC (hmacKey, plaintext))
{
secret.zero ();
hmacKey.zero ();
EVP_CIPHER_CTX_cleanup (&ctx);
Throw<std::runtime_error> ("plaintext had bad hmac");
}
secret.zero ();
hmacKey.zero ();
EVP_CIPHER_CTX_cleanup (&ctx);
return plaintext;
}
} // ripple

View File

@@ -21,7 +21,6 @@
#include <ripple/crypto/impl/ec_key.cpp>
#include <ripple/crypto/impl/ECDSAKey.cpp>
#include <ripple/crypto/impl/ECIES.cpp>
#include <ripple/crypto/impl/GenerateDeterministicKey.cpp>
#include <ripple/crypto/impl/KeyType.cpp>
#include <ripple/crypto/impl/openssl.cpp>