Skip to content
Permalink
Browse files

Merging new algorithms, untested

  • Loading branch information
Etienne Cimon
Etienne Cimon committed Jul 2, 2015
1 parent 8d43b64 commit 12c0c2cc4413f11db6c3c7cb15bbf839d4852717
@@ -53,6 +53,10 @@ snail-mail address (S), and Bitcoin address (B).
E: vojtech@kral.hk
D: LZMA compression module
S: Czech Republic
N: Adam Langley
E: agl@imperialviolet.org
D: Curve25519
N: Jack Lloyd
E: lloyd@randombit.net
@@ -19,10 +19,12 @@ Botan (http://botan.randombit.net/) is distributed under these terms:
2007 Manuel Hartl
2007 Christoph Ludwig
2007 Patrick Sona
2008 Google Inc.
2010 Olivier de Gaalon
2012 Vojtech Kral
2012-2014 Markus Wanner
2013 Joel Low
2014 Andrew Moon
2014-2015 Etienne Cimon
All rights reserved.
@@ -12,10 +12,11 @@
{
"name": "full",

"versions-x86_64": ["CanTest", "SHA2_32", "SHA2_64", "MD4", "MD5", "SHA1", "CRC24", "PBKDF1", "PBKDF2", "CTR_BE", "HMAC",
"versions-x86_64": ["CanTest", "SHA2_32", "SHA2_64", "MD4", "MD5", "SHA1", "CRC24", "PBKDF1", "PBKDF2", "CTR_BE", "HMAC", "POLY1305",
"EMSA1", "EMSA1_BSI", "EMSA_X931", "EMSA_PKCS1", "EMSA_PSSR", "EMSA_RAW", "EME_OAEP", "EME_PKCS1v15", "PBE_PKCSv20",
"Self_Tests", "ECB", "CBC", "XTS", "OFB", "CFB",
"AEAD_FILTER", "AEAD_CCM", "AEAD_EAX", "AEAD_OCB", "AEAD_GCM", "GCM_CLMUL", "AEAD_SIV", "RFC6979", "RSA", "RW", "DLIES", "DSA", "ECDSA", "ElGamal", "GOST_3410",
"AEAD_FILTER", "AEAD_CCM", "AEAD_EAX", "AEAD_OCB", "AEAD_GCM", "AEAD_CHACHA20_POLY1305", "GCM_CLMUL", "AEAD_SIV", "RFC6979", "RSA", "RW",
"DLIES", "DSA", "ECDSA", "ElGamal", "GOST_3410", "Curve22519",
"Nyberg_Rueppel", "Diffie_Hellman", "ECDH", "AES", "Blowfish", "Camellia", "CAST", "Cascade", "DES", "GOST_28147", "IDEA",
"KASUMI", "LION", "MARS", "MISTY1", "NOEKEON", "RC2", "RC5", "RC6", "SAFER", "SEED", "Serpent", "TEA", "Twofish", "Threefish",
"XTEA", "Adler32", "CRC32", "GOST_3411", "HAS_160", "Keccak", "MD2", "RIPEMD_128", "RIPEMD_160", "SHA1_x86_64",
@@ -28,10 +29,11 @@
"CryptoBox_PSK", "ZLib"],

"versions-x86": ["CanTest", "Serpent_x86_32", "MD4_x86_32", "MD5_x86_32", "SHA1_x86_32",
"SHA2_32", "SHA2_64", "MD4", "MD5", "SHA1", "CRC24", "PBKDF1", "PBKDF2", "CTR_BE", "HMAC",
"SHA2_32", "SHA2_64", "MD4", "MD5", "SHA1", "CRC24", "PBKDF1", "PBKDF2", "CTR_BE", "HMAC", "POLY1305",
"EMSA1", "EMSA1_BSI", "EMSA_X931", "EMSA_PKCS1", "EMSA_PSSR", "EMSA_RAW", "EME_OAEP", "EME_PKCS1v15", "PBE_PKCSv20",
"Self_Tests", "ECB", "CBC", "XTS", "OFB", "CFB",
"AEAD_FILTER", "AEAD_CCM", "AEAD_EAX", "AEAD_OCB", "AEAD_GCM", "AEAD_SIV", "RFC6979", "RSA", "RW", "DLIES", "DSA", "ECDSA", "ElGamal", "GOST_3410",
"AEAD_FILTER", "AEAD_CCM", "AEAD_EAX", "AEAD_OCB", "AEAD_GCM", "AEAD_SIV", "AEAD_CHACHA20_POLY1305",
"RFC6979", "RSA", "RW", "DLIES", "DSA", "ECDSA", "ElGamal", "GOST_3410", "Curve22519",
"Nyberg_Rueppel", "Diffie_Hellman", "ECDH", "AES", "Blowfish", "Camellia", "CAST", "Cascade", "DES", "GOST_28147", "IDEA",
"KASUMI", "LION", "MARS", "MISTY1", "NOEKEON", "RC2", "RC5", "RC6", "SAFER", "SEED", "Serpent", "TEA", "Twofish", "Threefish",
"XTEA", "Adler32", "CRC32", "GOST_3411", "HAS_160", "Keccak", "MD2", "RIPEMD_128", "RIPEMD_160",
@@ -46,10 +48,11 @@
{
"name": "32mscoff",
"versions": ["CanTest", "Serpent_x86_32", "MD4_x86_32", "MD5_x86_32", "SHA1_x86_32",
"SHA2_32", "SHA2_64", "MD4", "MD5", "SHA1", "CRC24", "PBKDF1", "PBKDF2", "CTR_BE", "HMAC",
"SHA2_32", "SHA2_64", "MD4", "MD5", "SHA1", "CRC24", "PBKDF1", "PBKDF2", "CTR_BE", "HMAC", "POLY1305",
"EMSA1", "EMSA1_BSI", "EMSA_X931", "EMSA_PKCS1", "EMSA_PSSR", "EMSA_RAW", "EME_OAEP", "EME_PKCS1v15", "PBE_PKCSv20",
"Self_Tests", "ECB", "CBC", "XTS", "OFB", "CFB",
"AEAD_FILTER", "AEAD_CCM", "AEAD_EAX", "AEAD_OCB", "AEAD_GCM", "AEAD_SIV", "RFC6979", "RSA", "RW", "DLIES", "DSA", "ECDSA", "ElGamal", "GOST_3410",
"AEAD_FILTER", "AEAD_CCM", "AEAD_EAX", "AEAD_OCB", "AEAD_GCM", "AEAD_SIV", "AEAD_CHACHA20_POLY1305",
"RFC6979", "RSA", "RW", "DLIES", "DSA", "ECDSA", "ElGamal", "GOST_3410", "Curve22519",
"Nyberg_Rueppel", "Diffie_Hellman", "ECDH", "AES", "Blowfish", "Camellia", "CAST", "Cascade", "DES", "GOST_28147", "IDEA",
"KASUMI", "LION", "MARS", "MISTY1", "NOEKEON", "RC2", "RC5", "RC6", "SAFER", "SEED", "Serpent", "TEA", "Twofish", "Threefish",
"XTEA", "Adler32", "CRC32", "GOST_3411", "HAS_160", "Keccak", "MD2", "RIPEMD_128", "RIPEMD_160",
@@ -71,7 +74,7 @@
{
"name": "pubkey",
"versions": ["Locking_Allocator", "SHA2_32", "SHA2_64", "MD4", "MD5", "SHA1", "CRC24", "Nyberg_Rueppel", "Diffie_Hellman", "ECDH", "PUBKEY", "X509",
"RSA", "RW", "DLIES", "DSA", "ECDSA", "ElGamal", "GOST_3410", "HMAC", "Entropy_HRTimer", "Entropy_Rdrand",
"RSA", "RW", "DLIES", "DSA", "ECDSA", "ElGamal", "GOST_3410", "Curve22519", "HMAC", "Entropy_HRTimer", "Entropy_Rdrand",
"Entropy_DevRand", "Entropy_EGD", "Entropy_UnixProc", "Entropy_CAPI", "Entropy_Win32", "Entropy_ProcWalk",
"KDF1", "KDF2", "SSL_V3_PRF", "TLS_V10_PRF", "TLS_V12_PRF", "X942_PRF" ]
},
@@ -144,8 +144,14 @@ public:
addOidstr("2.16.840.1.101.3.4.1.42", "AES-256/CBC");
addOidstr("1.2.410.200004.1.4", "SEED/CBC"); // RFC 4010
addOidstr("1.3.6.1.4.1.25258.3.1", "Serpent/CBC");

/* Hash Functions */
add_oidstr("1.3.6.1.4.1.25258.3.2", "Threefish-512/CBC");
add_oidstr("1.3.6.1.4.1.25258.3.3", "Twofish/CBC");
add_oidstr("2.16.840.1.101.3.4.1.6", "AES-128/GCM");
add_oidstr("2.16.840.1.101.3.4.1.26", "AES-192/GCM");
add_oidstr("2.16.840.1.101.3.4.1.46", "AES-256/GCM");
add_oidstr("1.3.6.1.4.1.25258.3.101", "Serpent/GCM");
add_oidstr("1.3.6.1.4.1.25258.3.102", "Twofish/GCM");
/* Hash Functions */
addOidstr("1.2.840.113549.2.5", "MD5");
addOidstr("1.3.6.1.4.1.11591.12.2", "Tiger(24,3)");

@@ -272,7 +272,13 @@ struct OnlineCheck {
/// TODO: Test OCSP with correct BER Decoding
logTrace("Checking OCSP online");
string responder_url;
synchronized(mtx) responder_url = (*cast(X509Certificate*)issuer).ocspResponder();
synchronized(mtx) {
if (!issuer) {
*cast(OCSPResponse*)resp = OCSPResponse.init;
return;
}
responder_url = (*cast(X509Certificate*)issuer).ocspResponder();
}
logTrace("Responder url: ", responder_url.length);

if (responder_url.length == 0) {
@@ -450,17 +450,23 @@ Vector!( RBTreeRef!CertificateStatusCode )

const CertificateStore* trusted = certstores.ptr;

if (i == 0 || restrictions.ocspAllIntermediates()) {
Mutex mtx = new Mutex;

ocsp_data.length = i + 1;
if (i == 0 || restrictions.ocspAllIntermediates()) {

//version(Have_vibe_d)
// Tid id_ = runTask(&onlineCheck, cast(shared)Tid.getThis(), cast(shared)i, cast(shared)&ocsp_data[i], cast(shared)&issuer, cast(shared)&subject, cast(shared)trusted);
//else
OnlineCheck oc = OnlineCheck( cast(shared)new Mutex, cast(shared)i, cast(shared)&ocsp_data[i], cast(shared)&issuer, cast(shared)&subject, cast(shared)trusted );
Thread thr = ThreadMem.alloc!Thread(&oc.run);
thr.start();
ocsp_responses ~= thr;
if (certstores.length > 1) {

//version(Have_vibe_d)
// Tid id_ = runTask(&onlineCheck, cast(shared)Tid.getThis(), cast(shared)i, cast(shared)&ocsp_data[i], cast(shared)&issuer, cast(shared)&subject, cast(shared)trusted);
//else
synchronized(mtx) {
ocsp_data.length = i + 1;
OnlineCheck oc = OnlineCheck( cast(shared)mtx, cast(shared)i, cast(shared)&ocsp_data[i], cast(shared)&issuer, cast(shared)&subject, cast(shared)trusted );
Thread thr = ThreadMem.alloc!Thread(&oc.run);
thr.start();
ocsp_responses ~= thr;
}
}
}
// Check all certs for valid time range
if (current_time < X509Time(subject.startTime()))
@@ -509,6 +515,7 @@ Vector!( RBTreeRef!CertificateStatusCode )
try
{
ocsp_responses[i].join();
if (ocsp_data.length <= i) continue;
OCSPResponse ocsp = ocsp_data[i];
logTrace("Got response for ID#", i.to!string);
if (!ocsp || ocsp.empty)
@@ -217,6 +217,8 @@ version(AEAD_GCM) { const BOTAN_HAS_AEAD_GCM = true;
else const BOTAN_HAS_AEAD_GCM = false;
version(AEAD_SIV) { const BOTAN_HAS_AEAD_SIV = true; }
else const BOTAN_HAS_AEAD_SIV = false;
version(AEAD_CHACHA20_POLY1305){const BOTAN_HAS_AEAD_CHACHA20_POLY1305 = true; }
else const BOTAN_HAS_AEAD_CHACHA20_POLY1305 = false;

version(RFC6979) { const BOTAN_HAS_RFC6979_GENERATOR = true; }
else const BOTAN_HAS_RFC6979_GENERATOR = false;
@@ -240,6 +242,8 @@ version(Diffie_Hellman) { const BOTAN_HAS_DIFFIE_HELLMAN = true;
else const BOTAN_HAS_DIFFIE_HELLMAN = false;
version(ECDH) { const BOTAN_HAS_ECDH = true; }
else const BOTAN_HAS_ECDH = false;
version(Curve22519) { const BOTAN_HAS_CURVE22519 = true; }
else const BOTAN_HAS_CURVE22519 = false;
version(AES) { const BOTAN_HAS_AES = true; }
else const BOTAN_HAS_AES = false;
version(Blowfish) { const BOTAN_HAS_BLOWFISH = true; }
@@ -324,6 +328,8 @@ version(ParallelHash) { const BOTAN_HAS_PARALLEL_HASH = true;
else const BOTAN_HAS_PARALLEL_HASH = false;
version(Comb4P) { const BOTAN_HAS_COMB4P = true; }
else const BOTAN_HAS_COMB4P = false;
version(POLY1305) { const BOTAN_HAS_POLY1305 = true; }
else const BOTAN_HAS_POLY1305 = false;
version(CBC_MAC) { const BOTAN_HAS_CBC_MAC = true; }
else const BOTAN_HAS_CBC_MAC = false;
version(CMAC) { const BOTAN_HAS_CMAC = true; }
@@ -0,0 +1,177 @@
/**
* PKCS #5 v2.0 PBE
*
* Copyright:
* (C) 1999-2007,2014 Jack Lloyd
* (C) 2014-2015 Etienne Cimon
*
* License:
* Botan is released under the Simplified BSD License (see LICENSE.md)
*/
module botan.constructs.pbes2;

import botan.utils.types;
import botan.algo_base.transform;
import std.datetime;
import botan.pbkdf.pbkdf;
import botan.asn1.ber_dec;
import botan.asn1.der_enc;
import botan.asn1.alg_id;
import botan.asn1.oids;
import botan.rng.rng;
import botan.utils.parsing;

/**
* Encrypt with PBES2 from PKCS #5 v2.0
* key_bits = the passphrase to use for encryption
* msec = how many milliseconds to run PBKDF2
* cipher = specifies the block cipher to use to encrypt
* digest = specifies the PRF to use with PBKDF2 (eg "HMAC(SHA-1)")
* rng = a random number generator
*/
Pair!(AlgorithmIdentifier, Vector!ubyte)
pbes2Encrypt(const ref SecureVector!ubyte key_bits,
const string passphrase,
Duration msec,
const string cipher,
const string digest,
RandomNumberGenerator rng)
{
const string prf = "HMAC(" ~ digest ~ ")";

const Vector!string cipher_spec = splitter(cipher, '/');
if(cipher_spec.length != 2)
throw new DecodingError("PBE-PKCS5 v2.0: Invalid cipher spec " ~ cipher);

const SecureVector!ubyte salt = rng.randomVec(12);

if(cipher_spec[1] != "CBC" && cipher_spec[1] != "GCM")
throw new DecodingError("PBE-PKCS5 v2.0: Don't know param format for " ~ cipher);

Unique!CipherMode enc = getCipherMode(cipher, ENCRYPTION);

Unique!PBKDF pbkdf = getPbkdf("PBKDF2(" ~ prf ~ ")");

const size_t key_length = enc.keySpec().maximumKeyLength();
size_t iterations = 0;

SecureVector!ubyte iv = rng.randomVec(enc.defaultNonceLength());

enc.setKey(pbkdf.deriveKey(key_length, passphrase, salt.ptr, salt.length,
msec, iterations).bitsOf());

enc.start(iv);
SecureVector!ubyte buf = key_bits;
enc.finish(buf);

AlgorithmIdentifier id = AlgorithmIdentifier(
OIDS.lookup("PBE-PKCS5v20"),
encodePbes2Params(cipher, prf, salt, iv, iterations, key_length));

return makePair(id, unlock(buf));

}
/*
* Encode PKCS#5 PBES2 parameters
*/
Vector!ubyte encodePbes2Params(const string cipher,
const string prf,
const ref SecureVector!ubyte salt,
const ref SecureVector!ubyte iv,
size_t iterations,
size_t key_length)
{
return DEREncoder()
.startCons(SEQUENCE)
.encode(AlgorithmIdentifier("PKCS5.PBKDF2",
DEREncoder()
.startCons(ASN1Tag.SEQUENCE)
.encode(salt, ASN1Tag.OCTET_STRING)
.encode(iterations)
.encode(key_length)
.encodeIf(prf != "HMAC(SHA-160)",
AlgorithmIdentifier(prf, AlgorithmIdentifierImpl.USE_NULL_PARAM))
.endCons()
.getContentsUnlocked()
)
)
.encode(
AlgorithmIdentifier(cipher,
DEREncoder().encode(iv, ASN1Tag.OCTET_STRING).getContentsUnlocked()
)
)
.endCons()
.getContentsUnlocked();
}


/**
* Decrypt a PKCS #5 v2.0 encrypted stream
* key_bits = the input
* passphrase = the passphrase to use for decryption
* params = the PBES2 parameters
*/
SecureVector!ubyte
pbes2Decrypt(const ref SecureVector!ubyte key_bits,
const string passphrase,
const ref Vector!ubyte params)
{
AlgorithmIdentifier kdf_algo, enc_algo;

BERDecoder(params)
.startCons(ASN1Tag.SEQUENCE)
.decode(kdf_algo)
.decode(enc_algo)
.verifyEnd()
.endCons();

AlgorithmIdentifier prf_algo;

if(kdf_algo.oid != OIDS.lookup("PKCS5.PBKDF2"))
throw new DecodingError("PBE-PKCS5 v2.0: Unknown KDF algorithm " ~ kdf_algo.oid.toString());

SecureVector!ubyte salt;
size_t iterations = 0, key_length = 0;

BERDecoder(kdf_algo.parameters)
.startCons(ASN1Tag.SEQUENCE)
.decode(salt, ASN1Tag.OCTET_STRING)
.decode(iterations)
.decode_optional(key_length, ASN1Tag.INTEGER, ASN1Tag.UNIVERSAL)
.decode_optional(prf_algo, ASN1Tag.SEQUENCE, ASN1Tag.CONSTRUCTED,
AlgorithmIdentifier("HMAC(SHA-160)",
AlgorithmIdentifierImpl.USE_NULL_PARAM))
.verifyEnd()
.endCons();

const string cipher = OIDS.lookup(enc_algo.oid);
const Vector!string cipher_spec = splitter(cipher, '/');
if(cipher_spec.length != 2)
throw new DecodingError("PBE-PKCS5 v2.0: Invalid cipher spec " ~ cipher);
if(cipher_spec[1] != "CBC" && cipher_spec[1] != "GCM")
throw new DecodingError("PBE-PKCS5 v2.0: Don't know param format for " ~ cipher);

if(salt.length < 8)
throw new DecodingError("PBE-PKCS5 v2.0: Encoded salt is too small");

SecureVector!ubyte iv;
BERDecoder(enc_algo.parameters).decode(iv, ASN1Tag.OCTET_STRING).verifyEnd();

const string prf = OIDS.lookup(prf_algo.oid);

Unique!PBKDF pbkdf = getPbkdf("PBKDF2(" ~ prf ~ ")");

Unique!Cipher_Mode dec = getCipherMode(cipher, DECRYPTION);

if(key_length == 0)
key_length = dec.keySpec().maximumKeyLength();

dec.set_key(pbkdf.deriveKey(key_length, passphrase, salt.ptr, salt.legth, iterations));

dec.start(iv);

SecureVector!ubyte buf = key_bits;
dec.finish(buf);

return buf.move();
}
@@ -100,6 +100,7 @@ static if (BOTAN_HAS_PARALLEL_HASH) import botan.hash.par_hash;
static if (BOTAN_HAS_COMB4P) import botan.hash.comb4p;

/// MAC
static if (BOTAN_HAS_POLY1305) import botan.mac.poly1305;
static if (BOTAN_HAS_CBC_MAC) import botan.mac.cbc_mac;
static if (BOTAN_HAS_CMAC) import botan.mac.cmac;
static if (BOTAN_HAS_HMAC) import botan.mac.hmac;
@@ -502,10 +503,6 @@ public:
override MessageAuthenticationCode findMac(in SCANToken request, AlgorithmFactory af) const
{
//logTrace("FindMac Core");
static if (BOTAN_HAS_CBC_MAC) {
if (request.algoName == "CBC-MAC" && request.argCount() == 1)
return new CBCMAC(af.makeBlockCipher(request.arg(0)));
}

static if (BOTAN_HAS_CMAC) {
if (request.algoName == "CMAC" && request.argCount() == 1)
@@ -518,6 +515,17 @@ public:
}
}

static if (BOTAN_HAS_POLY1305) {
if (request.algoName == "POLY1305") {
return new Poly1305;
}
}

static if (BOTAN_HAS_CBC_MAC) {
if (request.algoName == "CBC-MAC" && request.argCount() == 1)
return new CBCMAC(af.makeBlockCipher(request.arg(0)));
}

static if (BOTAN_HAS_SSL3_MAC) {
if (request.algoName == "SSL3-MAC" && request.argCount() == 1)
return new SSL3MAC(af.makeHashFunction(request.arg(0)));

0 comments on commit 12c0c2c

Please sign in to comment.
You can’t perform that action at this time.