Drop 3DES and other unneeded functions

This commit is contained in:
UnknownShadow200 2025-06-28 13:36:45 +10:00
parent 9c6895247d
commit 8ce38175f5
17 changed files with 3 additions and 3172 deletions

View File

@ -299,13 +299,6 @@ extern "C" {
* | aes_ct | AES | 16 | 16, 24 and 32 |
* | aes_ct64 | AES | 16 | 16, 24 and 32 |
* | aes_x86ni | AES | 16 | 16, 24 and 32 |
* | des_ct | DES/3DES | 8 | 8, 16 and 24 |
* | des_tab | DES/3DES | 8 | 8, 16 and 24 |
*
* **Note:** DES/3DES nominally uses keys of 64, 128 and 192 bits (i.e. 8,
* 16 and 24 bytes), but some of the bits are ignored by the algorithm, so
* the _effective_ key lengths, from a security point of view, are 56,
* 112 and 168 bits, respectively.
*
* `aes_big` is a "classical" AES implementation, using tables. It
* is fast but not constant-time, since it makes data-dependent array
@ -334,12 +327,6 @@ extern "C" {
* `aes_x86ni` exists only on x86 architectures (32-bit and 64-bit). It
* uses the AES-NI opcodes when available.
*
* `des_tab` is a classic, table-based implementation of DES/3DES. It
* is not constant-time.
*
* `des_ct` is an constant-time implementation of DES/3DES. It is
* substantially slower than `des_tab`.
*
* ## ChaCha20 and Poly1305
*
* ChaCha20 is a stream cipher. Poly1305 is a MAC algorithm. They
@ -1898,215 +1885,6 @@ typedef union {
br_aes_x86ni_ctrcbc_keys c_x86ni;
} br_aes_gen_ctrcbc_keys;
/*
* Traditional, table-based implementation for DES/3DES. Since tables are
* used, cache-timing attacks are conceptually possible.
*/
/** \brief DES/3DES block size (8 bytes). */
#define br_des_tab_BLOCK_SIZE 8
/**
* \brief Context for DES subkeys (`des_tab` implementation, CBC encryption).
*
* First field is a pointer to the vtable; it is set by the initialisation
* function. Other fields are not supposed to be accessed by user code.
*/
typedef struct {
/** \brief Pointer to vtable for this context. */
const br_block_cbcenc_class *vtable;
#ifndef BR_DOXYGEN_IGNORE
uint32_t skey[96];
unsigned num_rounds;
#endif
} br_des_tab_cbcenc_keys;
/**
* \brief Context for DES subkeys (`des_tab` implementation, CBC decryption).
*
* First field is a pointer to the vtable; it is set by the initialisation
* function. Other fields are not supposed to be accessed by user code.
*/
typedef struct {
/** \brief Pointer to vtable for this context. */
const br_block_cbcdec_class *vtable;
#ifndef BR_DOXYGEN_IGNORE
uint32_t skey[96];
unsigned num_rounds;
#endif
} br_des_tab_cbcdec_keys;
/**
* \brief Class instance for DES CBC encryption (`des_tab` implementation).
*/
extern const br_block_cbcenc_class br_des_tab_cbcenc_vtable;
/**
* \brief Class instance for DES CBC decryption (`des_tab` implementation).
*/
extern const br_block_cbcdec_class br_des_tab_cbcdec_vtable;
/**
* \brief Context initialisation (key schedule) for DES CBC encryption
* (`des_tab` implementation).
*
* \param ctx context to initialise.
* \param key secret key.
* \param len secret key length (in bytes).
*/
void br_des_tab_cbcenc_init(br_des_tab_cbcenc_keys *ctx,
const void *key, size_t len);
/**
* \brief Context initialisation (key schedule) for DES CBC decryption
* (`des_tab` implementation).
*
* \param ctx context to initialise.
* \param key secret key.
* \param len secret key length (in bytes).
*/
void br_des_tab_cbcdec_init(br_des_tab_cbcdec_keys *ctx,
const void *key, size_t len);
/**
* \brief CBC encryption with DES (`des_tab` implementation).
*
* \param ctx context (already initialised).
* \param iv IV (updated).
* \param data data to encrypt (updated).
* \param len data length (in bytes, MUST be multiple of 8).
*/
void br_des_tab_cbcenc_run(const br_des_tab_cbcenc_keys *ctx, void *iv,
void *data, size_t len);
/**
* \brief CBC decryption with DES (`des_tab` implementation).
*
* \param ctx context (already initialised).
* \param iv IV (updated).
* \param data data to decrypt (updated).
* \param len data length (in bytes, MUST be multiple of 8).
*/
void br_des_tab_cbcdec_run(const br_des_tab_cbcdec_keys *ctx, void *iv,
void *data, size_t len);
/*
* Constant-time implementation for DES/3DES. It is substantially slower
* (by a factor of about 4x), but also immune to cache-timing attacks.
*/
/** \brief DES/3DES block size (8 bytes). */
#define br_des_ct_BLOCK_SIZE 8
/**
* \brief Context for DES subkeys (`des_ct` implementation, CBC encryption).
*
* First field is a pointer to the vtable; it is set by the initialisation
* function. Other fields are not supposed to be accessed by user code.
*/
typedef struct {
/** \brief Pointer to vtable for this context. */
const br_block_cbcenc_class *vtable;
#ifndef BR_DOXYGEN_IGNORE
uint32_t skey[96];
unsigned num_rounds;
#endif
} br_des_ct_cbcenc_keys;
/**
* \brief Context for DES subkeys (`des_ct` implementation, CBC decryption).
*
* First field is a pointer to the vtable; it is set by the initialisation
* function. Other fields are not supposed to be accessed by user code.
*/
typedef struct {
/** \brief Pointer to vtable for this context. */
const br_block_cbcdec_class *vtable;
#ifndef BR_DOXYGEN_IGNORE
uint32_t skey[96];
unsigned num_rounds;
#endif
} br_des_ct_cbcdec_keys;
/**
* \brief Class instance for DES CBC encryption (`des_ct` implementation).
*/
extern const br_block_cbcenc_class br_des_ct_cbcenc_vtable;
/**
* \brief Class instance for DES CBC decryption (`des_ct` implementation).
*/
extern const br_block_cbcdec_class br_des_ct_cbcdec_vtable;
/**
* \brief Context initialisation (key schedule) for DES CBC encryption
* (`des_ct` implementation).
*
* \param ctx context to initialise.
* \param key secret key.
* \param len secret key length (in bytes).
*/
void br_des_ct_cbcenc_init(br_des_ct_cbcenc_keys *ctx,
const void *key, size_t len);
/**
* \brief Context initialisation (key schedule) for DES CBC decryption
* (`des_ct` implementation).
*
* \param ctx context to initialise.
* \param key secret key.
* \param len secret key length (in bytes).
*/
void br_des_ct_cbcdec_init(br_des_ct_cbcdec_keys *ctx,
const void *key, size_t len);
/**
* \brief CBC encryption with DES (`des_ct` implementation).
*
* \param ctx context (already initialised).
* \param iv IV (updated).
* \param data data to encrypt (updated).
* \param len data length (in bytes, MUST be multiple of 8).
*/
void br_des_ct_cbcenc_run(const br_des_ct_cbcenc_keys *ctx, void *iv,
void *data, size_t len);
/**
* \brief CBC decryption with DES (`des_ct` implementation).
*
* \param ctx context (already initialised).
* \param iv IV (updated).
* \param data data to decrypt (updated).
* \param len data length (in bytes, MUST be multiple of 8).
*/
void br_des_ct_cbcdec_run(const br_des_ct_cbcdec_keys *ctx, void *iv,
void *data, size_t len);
/*
* These structures are large enough to accommodate subkeys for all
* DES/3DES implementations.
*/
/**
* \brief Aggregate structure large enough to be used as context for
* subkeys (CBC encryption) for all DES implementations.
*/
typedef union {
const br_block_cbcenc_class *vtable;
br_des_tab_cbcenc_keys tab;
br_des_ct_cbcenc_keys ct;
} br_des_gen_cbcenc_keys;
/**
* \brief Aggregate structure large enough to be used as context for
* subkeys (CBC decryption) for all DES implementations.
*/
typedef union {
const br_block_cbcdec_class *vtable;
br_des_tab_cbcdec_keys c_tab;
br_des_ct_cbcdec_keys c_ct;
} br_des_gen_cbcdec_keys;
/**
* \brief Type for a ChaCha20 implementation.
*

File diff suppressed because it is too large Load Diff

View File

@ -1,411 +0,0 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "inner.h"
/*
* During key schedule, we need to apply bit extraction PC-2 then permute
* things into our bitslice representation. PC-2 extracts 48 bits out
* of two 28-bit words (kl and kr), and we store these bits into two
* 32-bit words sk0 and sk1.
*
* -- bit 16+x of sk0 comes from bit QL0[x] of kl
* -- bit x of sk0 comes from bit QR0[x] of kr
* -- bit 16+x of sk1 comes from bit QL1[x] of kl
* -- bit x of sk1 comes from bit QR1[x] of kr
*/
static const unsigned char QL0[] = {
17, 4, 27, 23, 13, 22, 7, 18,
16, 24, 2, 20, 1, 8, 15, 26
};
static const unsigned char QR0[] = {
25, 19, 9, 1, 5, 11, 23, 8,
17, 0, 22, 3, 6, 20, 27, 24
};
static const unsigned char QL1[] = {
28, 28, 14, 11, 28, 28, 25, 0,
28, 28, 5, 9, 28, 28, 12, 21
};
static const unsigned char QR1[] = {
28, 28, 15, 4, 28, 28, 26, 16,
28, 28, 12, 7, 28, 28, 10, 14
};
/*
* 32-bit rotation. The C compiler is supposed to recognize it as a
* rotation and use the local architecture rotation opcode (if available).
*/
static inline uint32_t
rotl(uint32_t x, int n)
{
return (x << n) | (x >> (32 - n));
}
/*
* Compute key schedule for 8 key bytes (produces 32 subkey words).
*/
static void
keysched_unit(uint32_t *skey, const void *key)
{
int i;
br_des_keysched_unit(skey, key);
/*
* Apply PC-2 + bitslicing.
*/
for (i = 0; i < 16; i ++) {
uint32_t kl, kr, sk0, sk1;
int j;
kl = skey[(i << 1) + 0];
kr = skey[(i << 1) + 1];
sk0 = 0;
sk1 = 0;
for (j = 0; j < 16; j ++) {
sk0 <<= 1;
sk1 <<= 1;
sk0 |= ((kl >> QL0[j]) & (uint32_t)1) << 16;
sk0 |= (kr >> QR0[j]) & (uint32_t)1;
sk1 |= ((kl >> QL1[j]) & (uint32_t)1) << 16;
sk1 |= (kr >> QR1[j]) & (uint32_t)1;
}
skey[(i << 1) + 0] = sk0;
skey[(i << 1) + 1] = sk1;
}
#if 0
/*
* Speed-optimized version for PC-2 + bitslicing.
* (Unused. Kept for reference only.)
*/
sk0 = kl & (uint32_t)0x00100000;
sk0 |= (kl & (uint32_t)0x08008000) << 2;
sk0 |= (kl & (uint32_t)0x00400000) << 4;
sk0 |= (kl & (uint32_t)0x00800000) << 5;
sk0 |= (kl & (uint32_t)0x00040000) << 6;
sk0 |= (kl & (uint32_t)0x00010000) << 7;
sk0 |= (kl & (uint32_t)0x00000100) << 10;
sk0 |= (kl & (uint32_t)0x00022000) << 14;
sk0 |= (kl & (uint32_t)0x00000082) << 18;
sk0 |= (kl & (uint32_t)0x00000004) << 19;
sk0 |= (kl & (uint32_t)0x04000000) >> 10;
sk0 |= (kl & (uint32_t)0x00000010) << 26;
sk0 |= (kl & (uint32_t)0x01000000) >> 2;
sk0 |= kr & (uint32_t)0x00000100;
sk0 |= (kr & (uint32_t)0x00000008) << 1;
sk0 |= (kr & (uint32_t)0x00000200) << 4;
sk0 |= rotl(kr & (uint32_t)0x08000021, 6);
sk0 |= (kr & (uint32_t)0x01000000) >> 24;
sk0 |= (kr & (uint32_t)0x00000002) << 11;
sk0 |= (kr & (uint32_t)0x00100000) >> 18;
sk0 |= (kr & (uint32_t)0x00400000) >> 17;
sk0 |= (kr & (uint32_t)0x00800000) >> 14;
sk0 |= (kr & (uint32_t)0x02020000) >> 10;
sk0 |= (kr & (uint32_t)0x00080000) >> 5;
sk0 |= (kr & (uint32_t)0x00000040) >> 3;
sk0 |= (kr & (uint32_t)0x00000800) >> 1;
sk1 = kl & (uint32_t)0x02000000;
sk1 |= (kl & (uint32_t)0x00001000) << 5;
sk1 |= (kl & (uint32_t)0x00000200) << 11;
sk1 |= (kl & (uint32_t)0x00004000) << 15;
sk1 |= (kl & (uint32_t)0x00000020) << 16;
sk1 |= (kl & (uint32_t)0x00000800) << 17;
sk1 |= (kl & (uint32_t)0x00000001) << 24;
sk1 |= (kl & (uint32_t)0x00200000) >> 5;
sk1 |= (kr & (uint32_t)0x00000010) << 8;
sk1 |= (kr & (uint32_t)0x04000000) >> 17;
sk1 |= (kr & (uint32_t)0x00004000) >> 14;
sk1 |= (kr & (uint32_t)0x00000400) >> 9;
sk1 |= (kr & (uint32_t)0x00010000) >> 8;
sk1 |= (kr & (uint32_t)0x00001000) >> 7;
sk1 |= (kr & (uint32_t)0x00000080) >> 3;
sk1 |= (kr & (uint32_t)0x00008000) >> 2;
#endif
}
/* see inner.h */
unsigned
br_des_ct_keysched(uint32_t *skey, const void *key, size_t key_len)
{
switch (key_len) {
case 8:
keysched_unit(skey, key);
return 1;
case 16:
keysched_unit(skey, key);
keysched_unit(skey + 32, (const unsigned char *)key + 8);
br_des_rev_skey(skey + 32);
memcpy(skey + 64, skey, 32 * sizeof *skey);
return 3;
default:
keysched_unit(skey, key);
keysched_unit(skey + 32, (const unsigned char *)key + 8);
br_des_rev_skey(skey + 32);
keysched_unit(skey + 64, (const unsigned char *)key + 16);
return 3;
}
}
/*
* DES confusion function. This function performs expansion E (32 to
* 48 bits), XOR with subkey, S-boxes, and permutation P.
*/
static inline uint32_t
Fconf(uint32_t r0, const uint32_t *sk)
{
/*
* Each 6->4 S-box is virtually turned into four 6->1 boxes; we
* thus end up with 32 boxes that we call "T-boxes" here. We will
* evaluate them with bitslice code.
*
* Each T-box is a circuit of multiplexers (sort of) and thus
* takes 70 inputs: the 6 actual T-box inputs, and 64 constants
* that describe the T-box output for all combinations of the
* 6 inputs. With this model, all T-boxes are identical (with
* distinct inputs) and thus can be executed in parallel with
* bitslice code.
*
* T-boxes are numbered from 0 to 31, in least-to-most
* significant order. Thus, S-box S1 corresponds to T-boxes 31,
* 30, 29 and 28, in that order. T-box 'n' is computed with the
* bits at rank 'n' in the 32-bit words.
*
* Words x0 to x5 contain the T-box inputs 0 to 5.
*/
uint32_t x0, x1, x2, x3, x4, x5, z0;
uint32_t y0, y1, y2, y3, y4, y5, y6, y7, y8, y9;
uint32_t y10, y11, y12, y13, y14, y15, y16, y17, y18, y19;
uint32_t y20, y21, y22, y23, y24, y25, y26, y27, y28, y29;
uint32_t y30;
/*
* Spread input bits over the 6 input words x*.
*/
x1 = r0 & (uint32_t)0x11111111;
x2 = (r0 >> 1) & (uint32_t)0x11111111;
x3 = (r0 >> 2) & (uint32_t)0x11111111;
x4 = (r0 >> 3) & (uint32_t)0x11111111;
x1 = (x1 << 4) - x1;
x2 = (x2 << 4) - x2;
x3 = (x3 << 4) - x3;
x4 = (x4 << 4) - x4;
x0 = (x4 << 4) | (x4 >> 28);
x5 = (x1 >> 4) | (x1 << 28);
/*
* XOR with the subkey for this round.
*/
x0 ^= sk[0];
x1 ^= sk[1];
x2 ^= sk[2];
x3 ^= sk[3];
x4 ^= sk[4];
x5 ^= sk[5];
/*
* The T-boxes are done in parallel, since they all use a
* "tree of multiplexer". We use "fake multiplexers":
*
* y = a ^ (x & b)
*
* computes y as either 'a' (if x == 0) or 'a ^ b' (if x == 1).
*/
y0 = (uint32_t)0xEFA72C4D ^ (x0 & (uint32_t)0xEC7AC69C);
y1 = (uint32_t)0xAEAAEDFF ^ (x0 & (uint32_t)0x500FB821);
y2 = (uint32_t)0x37396665 ^ (x0 & (uint32_t)0x40EFA809);
y3 = (uint32_t)0x68D7B833 ^ (x0 & (uint32_t)0xA5EC0B28);
y4 = (uint32_t)0xC9C755BB ^ (x0 & (uint32_t)0x252CF820);
y5 = (uint32_t)0x73FC3606 ^ (x0 & (uint32_t)0x40205801);
y6 = (uint32_t)0xA2A0A918 ^ (x0 & (uint32_t)0xE220F929);
y7 = (uint32_t)0x8222BD90 ^ (x0 & (uint32_t)0x44A3F9E1);
y8 = (uint32_t)0xD6B6AC77 ^ (x0 & (uint32_t)0x794F104A);
y9 = (uint32_t)0x3069300C ^ (x0 & (uint32_t)0x026F320B);
y10 = (uint32_t)0x6CE0D5CC ^ (x0 & (uint32_t)0x7640B01A);
y11 = (uint32_t)0x59A9A22D ^ (x0 & (uint32_t)0x238F1572);
y12 = (uint32_t)0xAC6D0BD4 ^ (x0 & (uint32_t)0x7A63C083);
y13 = (uint32_t)0x21C83200 ^ (x0 & (uint32_t)0x11CCA000);
y14 = (uint32_t)0xA0E62188 ^ (x0 & (uint32_t)0x202F69AA);
/* y15 = (uint32_t)0x00000000 ^ (x0 & (uint32_t)0x00000000); */
y16 = (uint32_t)0xAF7D655A ^ (x0 & (uint32_t)0x51B33BE9);
y17 = (uint32_t)0xF0168AA3 ^ (x0 & (uint32_t)0x3B0FE8AE);
y18 = (uint32_t)0x90AA30C6 ^ (x0 & (uint32_t)0x90BF8816);
y19 = (uint32_t)0x5AB2750A ^ (x0 & (uint32_t)0x09E34F9B);
y20 = (uint32_t)0x5391BE65 ^ (x0 & (uint32_t)0x0103BE88);
y21 = (uint32_t)0x93372BAF ^ (x0 & (uint32_t)0x49AC8E25);
y22 = (uint32_t)0xF288210C ^ (x0 & (uint32_t)0x922C313D);
y23 = (uint32_t)0x920AF5C0 ^ (x0 & (uint32_t)0x70EF31B0);
y24 = (uint32_t)0x63D312C0 ^ (x0 & (uint32_t)0x6A707100);
y25 = (uint32_t)0x537B3006 ^ (x0 & (uint32_t)0xB97C9011);
y26 = (uint32_t)0xA2EFB0A5 ^ (x0 & (uint32_t)0xA320C959);
y27 = (uint32_t)0xBC8F96A5 ^ (x0 & (uint32_t)0x6EA0AB4A);
y28 = (uint32_t)0xFAD176A5 ^ (x0 & (uint32_t)0x6953DDF8);
y29 = (uint32_t)0x665A14A3 ^ (x0 & (uint32_t)0xF74F3E2B);
y30 = (uint32_t)0xF2EFF0CC ^ (x0 & (uint32_t)0xF0306CAD);
/* y31 = (uint32_t)0x00000000 ^ (x0 & (uint32_t)0x00000000); */
y0 = y0 ^ (x1 & y1);
y1 = y2 ^ (x1 & y3);
y2 = y4 ^ (x1 & y5);
y3 = y6 ^ (x1 & y7);
y4 = y8 ^ (x1 & y9);
y5 = y10 ^ (x1 & y11);
y6 = y12 ^ (x1 & y13);
y7 = y14; /* was: y14 ^ (x1 & y15) */
y8 = y16 ^ (x1 & y17);
y9 = y18 ^ (x1 & y19);
y10 = y20 ^ (x1 & y21);
y11 = y22 ^ (x1 & y23);
y12 = y24 ^ (x1 & y25);
y13 = y26 ^ (x1 & y27);
y14 = y28 ^ (x1 & y29);
y15 = y30; /* was: y30 ^ (x1 & y31) */
y0 = y0 ^ (x2 & y1);
y1 = y2 ^ (x2 & y3);
y2 = y4 ^ (x2 & y5);
y3 = y6 ^ (x2 & y7);
y4 = y8 ^ (x2 & y9);
y5 = y10 ^ (x2 & y11);
y6 = y12 ^ (x2 & y13);
y7 = y14 ^ (x2 & y15);
y0 = y0 ^ (x3 & y1);
y1 = y2 ^ (x3 & y3);
y2 = y4 ^ (x3 & y5);
y3 = y6 ^ (x3 & y7);
y0 = y0 ^ (x4 & y1);
y1 = y2 ^ (x4 & y3);
y0 = y0 ^ (x5 & y1);
/*
* The P permutation:
* -- Each bit move is converted into a mask + left rotation.
* -- Rotations that use the same movement are coalesced together.
* -- Left and right shifts are used as alternatives to a rotation
* where appropriate (this will help architectures that do not have
* a rotation opcode).
*/
z0 = (y0 & (uint32_t)0x00000004) << 3;
z0 |= (y0 & (uint32_t)0x00004000) << 4;
z0 |= rotl(y0 & 0x12020120, 5);
z0 |= (y0 & (uint32_t)0x00100000) << 6;
z0 |= (y0 & (uint32_t)0x00008000) << 9;
z0 |= (y0 & (uint32_t)0x04000000) >> 22;
z0 |= (y0 & (uint32_t)0x00000001) << 11;
z0 |= rotl(y0 & 0x20000200, 12);
z0 |= (y0 & (uint32_t)0x00200000) >> 19;
z0 |= (y0 & (uint32_t)0x00000040) << 14;
z0 |= (y0 & (uint32_t)0x00010000) << 15;
z0 |= (y0 & (uint32_t)0x00000002) << 16;
z0 |= rotl(y0 & 0x40801800, 17);
z0 |= (y0 & (uint32_t)0x00080000) >> 13;
z0 |= (y0 & (uint32_t)0x00000010) << 21;
z0 |= (y0 & (uint32_t)0x01000000) >> 10;
z0 |= rotl(y0 & 0x88000008, 24);
z0 |= (y0 & (uint32_t)0x00000480) >> 7;
z0 |= (y0 & (uint32_t)0x00442000) >> 6;
return z0;
}
/*
* Process one block through 16 successive rounds, omitting the swap
* in the final round.
*/
static void
process_block_unit(uint32_t *pl, uint32_t *pr, const uint32_t *sk_exp)
{
int i;
uint32_t l, r;
l = *pl;
r = *pr;
for (i = 0; i < 16; i ++) {
uint32_t t;
t = l ^ Fconf(r, sk_exp);
l = r;
r = t;
sk_exp += 6;
}
*pl = r;
*pr = l;
}
/* see inner.h */
void
br_des_ct_process_block(unsigned num_rounds,
const uint32_t *sk_exp, void *block)
{
unsigned char *buf;
uint32_t l, r;
buf = block;
l = br_dec32be(buf);
r = br_dec32be(buf + 4);
br_des_do_IP(&l, &r);
while (num_rounds -- > 0) {
process_block_unit(&l, &r, sk_exp);
sk_exp += 96;
}
br_des_do_invIP(&l, &r);
br_enc32be(buf, l);
br_enc32be(buf + 4, r);
}
/* see inner.h */
void
br_des_ct_skey_expand(uint32_t *sk_exp,
unsigned num_rounds, const uint32_t *skey)
{
num_rounds <<= 4;
while (num_rounds -- > 0) {
uint32_t v, w0, w1, w2, w3;
v = *skey ++;
w0 = v & 0x11111111;
w1 = (v >> 1) & 0x11111111;
w2 = (v >> 2) & 0x11111111;
w3 = (v >> 3) & 0x11111111;
*sk_exp ++ = (w0 << 4) - w0;
*sk_exp ++ = (w1 << 4) - w1;
*sk_exp ++ = (w2 << 4) - w2;
*sk_exp ++ = (w3 << 4) - w3;
v = *skey ++;
w0 = v & 0x11111111;
w1 = (v >> 1) & 0x11111111;
*sk_exp ++ = (w0 << 4) - w0;
*sk_exp ++ = (w1 << 4) - w1;
}
}

View File

@ -1,87 +0,0 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "inner.h"
/* see bearssl_block.h */
void
br_des_ct_cbcdec_init(br_des_ct_cbcdec_keys *ctx,
const void *key, size_t len)
{
ctx->vtable = &br_des_ct_cbcdec_vtable;
ctx->num_rounds = br_des_ct_keysched(ctx->skey, key, len);
if (len == 8) {
br_des_rev_skey(ctx->skey);
} else {
int i;
for (i = 0; i < 48; i += 2) {
uint32_t t;
t = ctx->skey[i];
ctx->skey[i] = ctx->skey[94 - i];
ctx->skey[94 - i] = t;
t = ctx->skey[i + 1];
ctx->skey[i + 1] = ctx->skey[95 - i];
ctx->skey[95 - i] = t;
}
}
}
/* see bearssl_block.h */
void
br_des_ct_cbcdec_run(const br_des_ct_cbcdec_keys *ctx,
void *iv, void *data, size_t len)
{
unsigned char *buf, *ivbuf;
uint32_t sk_exp[288];
br_des_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey);
ivbuf = iv;
buf = data;
while (len > 0) {
unsigned char tmp[8];
int i;
memcpy(tmp, buf, 8);
br_des_ct_process_block(ctx->num_rounds, sk_exp, buf);
for (i = 0; i < 8; i ++) {
buf[i] ^= ivbuf[i];
}
memcpy(ivbuf, tmp, 8);
buf += 8;
len -= 8;
}
}
/* see bearssl_block.h */
const br_block_cbcdec_class br_des_ct_cbcdec_vtable = {
sizeof(br_des_ct_cbcdec_keys),
8,
3,
(void (*)(const br_block_cbcdec_class **, const void *, size_t))
&br_des_ct_cbcdec_init,
(void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t))
&br_des_ct_cbcdec_run
};

View File

@ -1,69 +0,0 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "inner.h"
/* see bearssl_block.h */
void
br_des_ct_cbcenc_init(br_des_ct_cbcenc_keys *ctx,
const void *key, size_t len)
{
ctx->vtable = &br_des_ct_cbcenc_vtable;
ctx->num_rounds = br_des_ct_keysched(ctx->skey, key, len);
}
/* see bearssl_block.h */
void
br_des_ct_cbcenc_run(const br_des_ct_cbcenc_keys *ctx,
void *iv, void *data, size_t len)
{
unsigned char *buf, *ivbuf;
uint32_t sk_exp[288];
br_des_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey);
ivbuf = iv;
buf = data;
while (len > 0) {
int i;
for (i = 0; i < 8; i ++) {
buf[i] ^= ivbuf[i];
}
br_des_ct_process_block(ctx->num_rounds, sk_exp, buf);
memcpy(ivbuf, buf, 8);
buf += 8;
len -= 8;
}
}
/* see bearssl_block.h */
const br_block_cbcenc_class br_des_ct_cbcenc_vtable = {
sizeof(br_des_ct_cbcenc_keys),
8,
3,
(void (*)(const br_block_cbcenc_class **, const void *, size_t))
&br_des_ct_cbcenc_init,
(void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t))
&br_des_ct_cbcenc_run
};

View File

@ -1,166 +0,0 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "inner.h"
/* see inner.h */
void
br_des_do_IP(uint32_t *xl, uint32_t *xr)
{
/*
* Permutation algorithm is initially from Richard Outerbridge;
* implementation here is adapted from Crypto++ "des.cpp" file
* (which is in public domain).
*/
uint32_t l, r, t;
l = *xl;
r = *xr;
t = ((l >> 4) ^ r) & (uint32_t)0x0F0F0F0F;
r ^= t;
l ^= t << 4;
t = ((l >> 16) ^ r) & (uint32_t)0x0000FFFF;
r ^= t;
l ^= t << 16;
t = ((r >> 2) ^ l) & (uint32_t)0x33333333;
l ^= t;
r ^= t << 2;
t = ((r >> 8) ^ l) & (uint32_t)0x00FF00FF;
l ^= t;
r ^= t << 8;
t = ((l >> 1) ^ r) & (uint32_t)0x55555555;
r ^= t;
l ^= t << 1;
*xl = l;
*xr = r;
}
/* see inner.h */
void
br_des_do_invIP(uint32_t *xl, uint32_t *xr)
{
/*
* See br_des_do_IP().
*/
uint32_t l, r, t;
l = *xl;
r = *xr;
t = ((l >> 1) ^ r) & 0x55555555;
r ^= t;
l ^= t << 1;
t = ((r >> 8) ^ l) & 0x00FF00FF;
l ^= t;
r ^= t << 8;
t = ((r >> 2) ^ l) & 0x33333333;
l ^= t;
r ^= t << 2;
t = ((l >> 16) ^ r) & 0x0000FFFF;
r ^= t;
l ^= t << 16;
t = ((l >> 4) ^ r) & 0x0F0F0F0F;
r ^= t;
l ^= t << 4;
*xl = l;
*xr = r;
}
/* see inner.h */
void
br_des_keysched_unit(uint32_t *skey, const void *key)
{
uint32_t xl, xr, kl, kr;
int i;
xl = br_dec32be(key);
xr = br_dec32be((const unsigned char *)key + 4);
/*
* Permutation PC-1 is quite similar to the IP permutation.
* Definition of IP (in FIPS 46-3 notations) is:
* 58 50 42 34 26 18 10 2
* 60 52 44 36 28 20 12 4
* 62 54 46 38 30 22 14 6
* 64 56 48 40 32 24 16 8
* 57 49 41 33 25 17 9 1
* 59 51 43 35 27 19 11 3
* 61 53 45 37 29 21 13 5
* 63 55 47 39 31 23 15 7
*
* Definition of PC-1 is:
* 57 49 41 33 25 17 9 1
* 58 50 42 34 26 18 10 2
* 59 51 43 35 27 19 11 3
* 60 52 44 36
* 63 55 47 39 31 23 15 7
* 62 54 46 38 30 22 14 6
* 61 53 45 37 29 21 13 5
* 28 20 12 4
*/
br_des_do_IP(&xl, &xr);
kl = ((xr & (uint32_t)0xFF000000) >> 4)
| ((xl & (uint32_t)0xFF000000) >> 12)
| ((xr & (uint32_t)0x00FF0000) >> 12)
| ((xl & (uint32_t)0x00FF0000) >> 20);
kr = ((xr & (uint32_t)0x000000FF) << 20)
| ((xl & (uint32_t)0x0000FF00) << 4)
| ((xr & (uint32_t)0x0000FF00) >> 4)
| ((xl & (uint32_t)0x000F0000) >> 16);
/*
* For each round, rotate the two 28-bit words kl and kr.
* The extraction of the 48-bit subkey (PC-2) is not done yet.
*/
for (i = 0; i < 16; i ++) {
if ((1 << i) & 0x8103) {
kl = (kl << 1) | (kl >> 27);
kr = (kr << 1) | (kr >> 27);
} else {
kl = (kl << 2) | (kl >> 26);
kr = (kr << 2) | (kr >> 26);
}
kl &= (uint32_t)0x0FFFFFFF;
kr &= (uint32_t)0x0FFFFFFF;
skey[(i << 1) + 0] = kl;
skey[(i << 1) + 1] = kr;
}
}
/* see inner.h */
void
br_des_rev_skey(uint32_t *skey)
{
int i;
for (i = 0; i < 16; i += 2) {
uint32_t t;
t = skey[i + 0];
skey[i + 0] = skey[30 - i];
skey[30 - i] = t;
t = skey[i + 1];
skey[i + 1] = skey[31 - i];
skey[31 - i] = t;
}
}

View File

@ -1,310 +0,0 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "inner.h"
/*
* PC2left[x] tells where bit x goes when applying PC-2. 'x' is a bit
* position in the left rotated key word. Both position are in normal
* order (rightmost bit is 0).
*/
static const unsigned char PC2left[] = {
16, 3, 7, 24, 20, 11, 24,
13, 2, 10, 24, 22, 5, 15,
23, 1, 9, 21, 12, 24, 6,
4, 14, 18, 8, 17, 0, 19
};
/*
* Similar to PC2left[x], for the right rotated key word.
*/
static const unsigned char PC2right[] = {
8, 18, 24, 6, 22, 15, 3,
10, 12, 19, 5, 14, 11, 24,
4, 23, 16, 9, 24, 20, 2,
24, 7, 13, 0, 21, 17, 1
};
/*
* S-boxes and PC-1 merged.
*/
static const uint32_t S1[] = {
0x00808200, 0x00000000, 0x00008000, 0x00808202,
0x00808002, 0x00008202, 0x00000002, 0x00008000,
0x00000200, 0x00808200, 0x00808202, 0x00000200,
0x00800202, 0x00808002, 0x00800000, 0x00000002,
0x00000202, 0x00800200, 0x00800200, 0x00008200,
0x00008200, 0x00808000, 0x00808000, 0x00800202,
0x00008002, 0x00800002, 0x00800002, 0x00008002,
0x00000000, 0x00000202, 0x00008202, 0x00800000,
0x00008000, 0x00808202, 0x00000002, 0x00808000,
0x00808200, 0x00800000, 0x00800000, 0x00000200,
0x00808002, 0x00008000, 0x00008200, 0x00800002,
0x00000200, 0x00000002, 0x00800202, 0x00008202,
0x00808202, 0x00008002, 0x00808000, 0x00800202,
0x00800002, 0x00000202, 0x00008202, 0x00808200,
0x00000202, 0x00800200, 0x00800200, 0x00000000,
0x00008002, 0x00008200, 0x00000000, 0x00808002
};
static const uint32_t S2[] = {
0x40084010, 0x40004000, 0x00004000, 0x00084010,
0x00080000, 0x00000010, 0x40080010, 0x40004010,
0x40000010, 0x40084010, 0x40084000, 0x40000000,
0x40004000, 0x00080000, 0x00000010, 0x40080010,
0x00084000, 0x00080010, 0x40004010, 0x00000000,
0x40000000, 0x00004000, 0x00084010, 0x40080000,
0x00080010, 0x40000010, 0x00000000, 0x00084000,
0x00004010, 0x40084000, 0x40080000, 0x00004010,
0x00000000, 0x00084010, 0x40080010, 0x00080000,
0x40004010, 0x40080000, 0x40084000, 0x00004000,
0x40080000, 0x40004000, 0x00000010, 0x40084010,
0x00084010, 0x00000010, 0x00004000, 0x40000000,
0x00004010, 0x40084000, 0x00080000, 0x40000010,
0x00080010, 0x40004010, 0x40000010, 0x00080010,
0x00084000, 0x00000000, 0x40004000, 0x00004010,
0x40000000, 0x40080010, 0x40084010, 0x00084000
};
static const uint32_t S3[] = {
0x00000104, 0x04010100, 0x00000000, 0x04010004,
0x04000100, 0x00000000, 0x00010104, 0x04000100,
0x00010004, 0x04000004, 0x04000004, 0x00010000,
0x04010104, 0x00010004, 0x04010000, 0x00000104,
0x04000000, 0x00000004, 0x04010100, 0x00000100,
0x00010100, 0x04010000, 0x04010004, 0x00010104,
0x04000104, 0x00010100, 0x00010000, 0x04000104,
0x00000004, 0x04010104, 0x00000100, 0x04000000,
0x04010100, 0x04000000, 0x00010004, 0x00000104,
0x00010000, 0x04010100, 0x04000100, 0x00000000,
0x00000100, 0x00010004, 0x04010104, 0x04000100,
0x04000004, 0x00000100, 0x00000000, 0x04010004,
0x04000104, 0x00010000, 0x04000000, 0x04010104,
0x00000004, 0x00010104, 0x00010100, 0x04000004,
0x04010000, 0x04000104, 0x00000104, 0x04010000,
0x00010104, 0x00000004, 0x04010004, 0x00010100
};
static const uint32_t S4[] = {
0x80401000, 0x80001040, 0x80001040, 0x00000040,
0x00401040, 0x80400040, 0x80400000, 0x80001000,
0x00000000, 0x00401000, 0x00401000, 0x80401040,
0x80000040, 0x00000000, 0x00400040, 0x80400000,
0x80000000, 0x00001000, 0x00400000, 0x80401000,
0x00000040, 0x00400000, 0x80001000, 0x00001040,
0x80400040, 0x80000000, 0x00001040, 0x00400040,
0x00001000, 0x00401040, 0x80401040, 0x80000040,
0x00400040, 0x80400000, 0x00401000, 0x80401040,
0x80000040, 0x00000000, 0x00000000, 0x00401000,
0x00001040, 0x00400040, 0x80400040, 0x80000000,
0x80401000, 0x80001040, 0x80001040, 0x00000040,
0x80401040, 0x80000040, 0x80000000, 0x00001000,
0x80400000, 0x80001000, 0x00401040, 0x80400040,
0x80001000, 0x00001040, 0x00400000, 0x80401000,
0x00000040, 0x00400000, 0x00001000, 0x00401040
};
static const uint32_t S5[] = {
0x00000080, 0x01040080, 0x01040000, 0x21000080,
0x00040000, 0x00000080, 0x20000000, 0x01040000,
0x20040080, 0x00040000, 0x01000080, 0x20040080,
0x21000080, 0x21040000, 0x00040080, 0x20000000,
0x01000000, 0x20040000, 0x20040000, 0x00000000,
0x20000080, 0x21040080, 0x21040080, 0x01000080,
0x21040000, 0x20000080, 0x00000000, 0x21000000,
0x01040080, 0x01000000, 0x21000000, 0x00040080,
0x00040000, 0x21000080, 0x00000080, 0x01000000,
0x20000000, 0x01040000, 0x21000080, 0x20040080,
0x01000080, 0x20000000, 0x21040000, 0x01040080,
0x20040080, 0x00000080, 0x01000000, 0x21040000,
0x21040080, 0x00040080, 0x21000000, 0x21040080,
0x01040000, 0x00000000, 0x20040000, 0x21000000,
0x00040080, 0x01000080, 0x20000080, 0x00040000,
0x00000000, 0x20040000, 0x01040080, 0x20000080
};
static const uint32_t S6[] = {
0x10000008, 0x10200000, 0x00002000, 0x10202008,
0x10200000, 0x00000008, 0x10202008, 0x00200000,
0x10002000, 0x00202008, 0x00200000, 0x10000008,
0x00200008, 0x10002000, 0x10000000, 0x00002008,
0x00000000, 0x00200008, 0x10002008, 0x00002000,
0x00202000, 0x10002008, 0x00000008, 0x10200008,
0x10200008, 0x00000000, 0x00202008, 0x10202000,
0x00002008, 0x00202000, 0x10202000, 0x10000000,
0x10002000, 0x00000008, 0x10200008, 0x00202000,
0x10202008, 0x00200000, 0x00002008, 0x10000008,
0x00200000, 0x10002000, 0x10000000, 0x00002008,
0x10000008, 0x10202008, 0x00202000, 0x10200000,
0x00202008, 0x10202000, 0x00000000, 0x10200008,
0x00000008, 0x00002000, 0x10200000, 0x00202008,
0x00002000, 0x00200008, 0x10002008, 0x00000000,
0x10202000, 0x10000000, 0x00200008, 0x10002008
};
static const uint32_t S7[] = {
0x00100000, 0x02100001, 0x02000401, 0x00000000,
0x00000400, 0x02000401, 0x00100401, 0x02100400,
0x02100401, 0x00100000, 0x00000000, 0x02000001,
0x00000001, 0x02000000, 0x02100001, 0x00000401,
0x02000400, 0x00100401, 0x00100001, 0x02000400,
0x02000001, 0x02100000, 0x02100400, 0x00100001,
0x02100000, 0x00000400, 0x00000401, 0x02100401,
0x00100400, 0x00000001, 0x02000000, 0x00100400,
0x02000000, 0x00100400, 0x00100000, 0x02000401,
0x02000401, 0x02100001, 0x02100001, 0x00000001,
0x00100001, 0x02000000, 0x02000400, 0x00100000,
0x02100400, 0x00000401, 0x00100401, 0x02100400,
0x00000401, 0x02000001, 0x02100401, 0x02100000,
0x00100400, 0x00000000, 0x00000001, 0x02100401,
0x00000000, 0x00100401, 0x02100000, 0x00000400,
0x02000001, 0x02000400, 0x00000400, 0x00100001
};
static const uint32_t S8[] = {
0x08000820, 0x00000800, 0x00020000, 0x08020820,
0x08000000, 0x08000820, 0x00000020, 0x08000000,
0x00020020, 0x08020000, 0x08020820, 0x00020800,
0x08020800, 0x00020820, 0x00000800, 0x00000020,
0x08020000, 0x08000020, 0x08000800, 0x00000820,
0x00020800, 0x00020020, 0x08020020, 0x08020800,
0x00000820, 0x00000000, 0x00000000, 0x08020020,
0x08000020, 0x08000800, 0x00020820, 0x00020000,
0x00020820, 0x00020000, 0x08020800, 0x00000800,
0x00000020, 0x08020020, 0x00000800, 0x00020820,
0x08000800, 0x00000020, 0x08000020, 0x08020000,
0x08020020, 0x08000000, 0x00020000, 0x08000820,
0x00000000, 0x08020820, 0x00020020, 0x08000020,
0x08020000, 0x08000800, 0x08000820, 0x00000000,
0x08020820, 0x00020800, 0x00020800, 0x00000820,
0x00000820, 0x00020020, 0x08000000, 0x08020800
};
static inline uint32_t
Fconf(uint32_t r0, uint32_t skl, uint32_t skr)
{
uint32_t r1;
r1 = (r0 << 16) | (r0 >> 16);
return
S1[((r1 >> 11) ^ (skl >> 18)) & 0x3F]
| S2[((r0 >> 23) ^ (skl >> 12)) & 0x3F]
| S3[((r0 >> 19) ^ (skl >> 6)) & 0x3F]
| S4[((r0 >> 15) ^ (skl )) & 0x3F]
| S5[((r0 >> 11) ^ (skr >> 18)) & 0x3F]
| S6[((r0 >> 7) ^ (skr >> 12)) & 0x3F]
| S7[((r0 >> 3) ^ (skr >> 6)) & 0x3F]
| S8[((r1 >> 15) ^ (skr )) & 0x3F];
}
static void
process_block_unit(uint32_t *pl, uint32_t *pr, const uint32_t *skey)
{
int i;
uint32_t l, r;
l = *pl;
r = *pr;
for (i = 0; i < 16; i ++) {
uint32_t t;
t = l ^ Fconf(r, skey[(i << 1) + 0], skey[(i << 1) + 1]);
l = r;
r = t;
}
*pl = r;
*pr = l;
}
/* see inner.h */
void
br_des_tab_process_block(unsigned num_rounds, const uint32_t *skey, void *block)
{
unsigned char *buf;
uint32_t l, r;
buf = block;
l = br_dec32be(buf);
r = br_dec32be(buf + 4);
br_des_do_IP(&l, &r);
while (num_rounds -- > 0) {
process_block_unit(&l, &r, skey);
skey += 32;
}
br_des_do_invIP(&l, &r);
br_enc32be(buf, l);
br_enc32be(buf + 4, r);
}
static void
keysched_unit(uint32_t *skey, const void *key)
{
int i;
br_des_keysched_unit(skey, key);
/*
* Apply PC-2 to get the 48-bit subkeys.
*/
for (i = 0; i < 16; i ++) {
uint32_t xl, xr, ul, ur;
int j;
xl = skey[(i << 1) + 0];
xr = skey[(i << 1) + 1];
ul = 0;
ur = 0;
for (j = 0; j < 28; j ++) {
ul |= (xl & 1) << PC2left[j];
ur |= (xr & 1) << PC2right[j];
xl >>= 1;
xr >>= 1;
}
skey[(i << 1) + 0] = ul;
skey[(i << 1) + 1] = ur;
}
}
/* see inner.h */
unsigned
br_des_tab_keysched(uint32_t *skey, const void *key, size_t key_len)
{
switch (key_len) {
case 8:
keysched_unit(skey, key);
return 1;
case 16:
keysched_unit(skey, key);
keysched_unit(skey + 32, (const unsigned char *)key + 8);
br_des_rev_skey(skey + 32);
memcpy(skey + 64, skey, 32 * sizeof *skey);
return 3;
default:
keysched_unit(skey, key);
keysched_unit(skey + 32, (const unsigned char *)key + 8);
br_des_rev_skey(skey + 32);
keysched_unit(skey + 64, (const unsigned char *)key + 16);
return 3;
}
}

View File

@ -1,85 +0,0 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "inner.h"
/* see bearssl_block.h */
void
br_des_tab_cbcdec_init(br_des_tab_cbcdec_keys *ctx,
const void *key, size_t len)
{
ctx->vtable = &br_des_tab_cbcdec_vtable;
ctx->num_rounds = br_des_tab_keysched(ctx->skey, key, len);
if (len == 8) {
br_des_rev_skey(ctx->skey);
} else {
int i;
for (i = 0; i < 48; i += 2) {
uint32_t t;
t = ctx->skey[i];
ctx->skey[i] = ctx->skey[94 - i];
ctx->skey[94 - i] = t;
t = ctx->skey[i + 1];
ctx->skey[i + 1] = ctx->skey[95 - i];
ctx->skey[95 - i] = t;
}
}
}
/* see bearssl_block.h */
void
br_des_tab_cbcdec_run(const br_des_tab_cbcdec_keys *ctx,
void *iv, void *data, size_t len)
{
unsigned char *buf, *ivbuf;
ivbuf = iv;
buf = data;
while (len > 0) {
unsigned char tmp[8];
int i;
memcpy(tmp, buf, 8);
br_des_tab_process_block(ctx->num_rounds, ctx->skey, buf);
for (i = 0; i < 8; i ++) {
buf[i] ^= ivbuf[i];
}
memcpy(ivbuf, tmp, 8);
buf += 8;
len -= 8;
}
}
/* see bearssl_block.h */
const br_block_cbcdec_class br_des_tab_cbcdec_vtable = {
sizeof(br_des_tab_cbcdec_keys),
8,
3,
(void (*)(const br_block_cbcdec_class **, const void *, size_t))
&br_des_tab_cbcdec_init,
(void (*)(const br_block_cbcdec_class *const *, void *, void *, size_t))
&br_des_tab_cbcdec_run
};

View File

@ -1,67 +0,0 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "inner.h"
/* see bearssl_block.h */
void
br_des_tab_cbcenc_init(br_des_tab_cbcenc_keys *ctx,
const void *key, size_t len)
{
ctx->vtable = &br_des_tab_cbcenc_vtable;
ctx->num_rounds = br_des_tab_keysched(ctx->skey, key, len);
}
/* see bearssl_block.h */
void
br_des_tab_cbcenc_run(const br_des_tab_cbcenc_keys *ctx,
void *iv, void *data, size_t len)
{
unsigned char *buf, *ivbuf;
ivbuf = iv;
buf = data;
while (len > 0) {
int i;
for (i = 0; i < 8; i ++) {
buf[i] ^= ivbuf[i];
}
br_des_tab_process_block(ctx->num_rounds, ctx->skey, buf);
memcpy(ivbuf, buf, 8);
buf += 8;
len -= 8;
}
}
/* see bearssl_block.h */
const br_block_cbcenc_class br_des_tab_cbcenc_vtable = {
sizeof(br_des_tab_cbcenc_keys),
8,
3,
(void (*)(const br_block_cbcenc_class **, const void *, size_t))
&br_des_tab_cbcenc_init,
(void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t))
&br_des_tab_cbcenc_run
};

View File

@ -36,7 +36,6 @@ br_ssl_client_init_full(br_ssl_client_context *cc,
* Rationale for suite order, from most important to least
* important rule:
*
* -- Don't use 3DES if AES or ChaCha20 is available.
* -- Try to have Forward Secrecy (ECDHE suite) if possible.
* -- When not using Forward Secrecy, ECDH key exchange is
* better than RSA key exchange (slightly more expensive on the
@ -89,12 +88,7 @@ br_ssl_client_init_full(br_ssl_client_context *cc,
BR_TLS_RSA_WITH_AES_128_CBC_SHA256,
BR_TLS_RSA_WITH_AES_256_CBC_SHA256,
BR_TLS_RSA_WITH_AES_128_CBC_SHA,
BR_TLS_RSA_WITH_AES_256_CBC_SHA,
BR_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
BR_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
BR_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
BR_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA
BR_TLS_RSA_WITH_AES_256_CBC_SHA
};
/*
@ -174,6 +168,5 @@ br_ssl_client_init_full(br_ssl_client_context *cc,
br_ssl_engine_set_default_aes_cbc(&cc->eng);
br_ssl_engine_set_default_aes_ccm(&cc->eng);
br_ssl_engine_set_default_aes_gcm(&cc->eng);
br_ssl_engine_set_default_des_cbc(&cc->eng);
br_ssl_engine_set_default_chapol(&cc->eng);
}

View File

@ -455,20 +455,6 @@ br_ssl_engine_init_rand(br_ssl_engine_context *cc)
return 0;
}
/*
* We always try OS/hardware seeding once. If it works, then
* we assume proper seeding. If not, then external entropy must
* have been injected; otherwise, we report an error.
*/
if (!cc->rng_os_rand_done) {
br_prng_seeder sd;
sd = br_prng_seeder_system(NULL);
if (sd != 0 && sd(&cc->rng.vtable)) {
cc->rng_init_done = 2;
}
cc->rng_os_rand_done = 1;
}
if (cc->rng_init_done < 2) {
br_ssl_engine_fail(cc, BR_ERR_NO_RANDOM);
return 0;

View File

@ -1,37 +0,0 @@
/*
* Copyright (c) 2017 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "inner.h"
/* see bearssl_ssl.h */
void
br_ssl_engine_set_default_des_cbc(br_ssl_engine_context *cc)
{
br_ssl_engine_set_cbc(cc,
&br_sslrec_in_cbc_vtable,
&br_sslrec_out_cbc_vtable);
br_ssl_engine_set_des_cbc(cc,
&br_des_ct_cbcenc_vtable,
&br_des_ct_cbcdec_vtable);
}

View File

@ -1714,7 +1714,7 @@ br_ssl_hs_client_run(void *t0ctx)
prf_id = T0_POP();
is_client = T0_POP();
br_ssl_engine_switch_cbc_in(ENG, is_client, prf_id, mac_id,
aes ? ENG->iaes_cbcdec : ENG->ides_cbcdec, cipher_key_len);
ENG->iaes_cbcdec, cipher_key_len);
}
break;
@ -1730,7 +1730,7 @@ br_ssl_hs_client_run(void *t0ctx)
prf_id = T0_POP();
is_client = T0_POP();
br_ssl_engine_switch_cbc_out(ENG, is_client, prf_id, mac_id,
aes ? ENG->iaes_cbcenc : ENG->ides_cbcenc, cipher_key_len);
ENG->iaes_cbcenc, cipher_key_len);
}
break;

View File

@ -1,83 +0,0 @@
/*
* Copyright (c) 2017 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "inner.h"
/*
* Supported cipher suites that use SHA-384 for the PRF when selected
* for TLS 1.2. All other cipher suites are deemed to use SHA-256.
*/
static const uint16_t suites_sha384[] = {
BR_TLS_RSA_WITH_AES_256_GCM_SHA384,
BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
};
/* see bearssl_ssl.h */
int
br_ssl_key_export(br_ssl_engine_context *cc,
void *dst, size_t len, const char *label,
const void *context, size_t context_len)
{
br_tls_prf_seed_chunk chunks[4];
br_tls_prf_impl iprf;
size_t num_chunks, u;
unsigned char tmp[2];
int prf_id;
if (cc->application_data != 1) {
return 0;
}
chunks[0].data = cc->client_random;
chunks[0].len = sizeof cc->client_random;
chunks[1].data = cc->server_random;
chunks[1].len = sizeof cc->server_random;
if (context != NULL) {
br_enc16be(tmp, (unsigned)context_len);
chunks[2].data = tmp;
chunks[2].len = 2;
chunks[3].data = context;
chunks[3].len = context_len;
num_chunks = 4;
} else {
num_chunks = 2;
}
prf_id = BR_SSLPRF_SHA256;
for (u = 0; u < (sizeof suites_sha384) / sizeof(uint16_t); u ++) {
if (suites_sha384[u] == cc->session.cipher_suite) {
prf_id = BR_SSLPRF_SHA384;
}
}
iprf = br_ssl_engine_get_PRF(cc, prf_id);
iprf(dst, len,
cc->session.master_secret, sizeof cc->session.master_secret,
label, num_chunks, chunks);
return 1;
}

View File

@ -1,142 +0,0 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "inner.h"
static int
se_choose(const br_ssl_server_policy_class **pctx,
const br_ssl_server_context *cc,
br_ssl_server_choices *choices)
{
br_ssl_server_policy_ec_context *pc;
const br_suite_translated *st;
size_t u, st_num;
unsigned hash_id;
pc = (br_ssl_server_policy_ec_context *)pctx;
st = br_ssl_server_get_client_suites(cc, &st_num);
hash_id = br_ssl_choose_hash(br_ssl_server_get_client_hashes(cc) >> 8);
if (cc->eng.session.version < BR_TLS12) {
hash_id = br_sha1_ID;
}
choices->chain = pc->chain;
choices->chain_len = pc->chain_len;
for (u = 0; u < st_num; u ++) {
unsigned tt;
tt = st[u][1];
switch (tt >> 12) {
case BR_SSLKEYX_ECDH_RSA:
if ((pc->allowed_usages & BR_KEYTYPE_KEYX) != 0
&& pc->cert_issuer_key_type == BR_KEYTYPE_RSA)
{
choices->cipher_suite = st[u][0];
return 1;
}
break;
case BR_SSLKEYX_ECDH_ECDSA:
if ((pc->allowed_usages & BR_KEYTYPE_KEYX) != 0
&& pc->cert_issuer_key_type == BR_KEYTYPE_EC)
{
choices->cipher_suite = st[u][0];
return 1;
}
break;
case BR_SSLKEYX_ECDHE_ECDSA:
if ((pc->allowed_usages & BR_KEYTYPE_SIGN) != 0
&& hash_id != 0)
{
choices->cipher_suite = st[u][0];
choices->algo_id = hash_id + 0xFF00;
return 1;
}
break;
}
}
return 0;
}
static uint32_t
se_do_keyx(const br_ssl_server_policy_class **pctx,
unsigned char *data, size_t *len)
{
br_ssl_server_policy_ec_context *pc;
uint32_t r;
size_t xoff, xlen;
pc = (br_ssl_server_policy_ec_context *)pctx;
r = pc->iec->mul(data, *len, pc->sk->x, pc->sk->xlen, pc->sk->curve);
xoff = pc->iec->xoff(pc->sk->curve, &xlen);
memmove(data, data + xoff, xlen);
*len = xlen;
return r;
}
static size_t
se_do_sign(const br_ssl_server_policy_class **pctx,
unsigned algo_id, unsigned char *data, size_t hv_len, size_t len)
{
br_ssl_server_policy_ec_context *pc;
unsigned char hv[64];
const br_hash_class *hc;
algo_id &= 0xFF;
pc = (br_ssl_server_policy_ec_context *)pctx;
hc = br_multihash_getimpl(pc->mhash, algo_id);
if (hc == NULL) {
return 0;
}
memcpy(hv, data, hv_len);
if (len < 139) {
return 0;
}
return pc->iecdsa(pc->iec, hc, hv, pc->sk, data);
}
static const br_ssl_server_policy_class se_policy_vtable = {
sizeof(br_ssl_server_policy_ec_context),
se_choose,
se_do_keyx,
se_do_sign
};
/* see bearssl_ssl.h */
void
br_ssl_server_set_single_ec(br_ssl_server_context *cc,
const br_x509_certificate *chain, size_t chain_len,
const br_ec_private_key *sk, unsigned allowed_usages,
unsigned cert_issuer_key_type,
const br_ec_impl *iec, br_ecdsa_sign iecdsa)
{
cc->chain_handler.single_ec.vtable = &se_policy_vtable;
cc->chain_handler.single_ec.chain = chain;
cc->chain_handler.single_ec.chain_len = chain_len;
cc->chain_handler.single_ec.sk = sk;
cc->chain_handler.single_ec.allowed_usages = allowed_usages;
cc->chain_handler.single_ec.cert_issuer_key_type = cert_issuer_key_type;
cc->chain_handler.single_ec.mhash = &cc->eng.mhash;
cc->chain_handler.single_ec.iec = iec;
cc->chain_handler.single_ec.iecdsa = iecdsa;
cc->policy_vtable = &cc->chain_handler.single_ec.vtable;
}

View File

@ -1,162 +0,0 @@
/*
* Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "inner.h"
static int
sr_choose(const br_ssl_server_policy_class **pctx,
const br_ssl_server_context *cc,
br_ssl_server_choices *choices)
{
br_ssl_server_policy_rsa_context *pc;
const br_suite_translated *st;
size_t u, st_num;
unsigned hash_id;
int fh;
pc = (br_ssl_server_policy_rsa_context *)pctx;
st = br_ssl_server_get_client_suites(cc, &st_num);
if (cc->eng.session.version < BR_TLS12) {
hash_id = 0;
fh = 1;
} else {
hash_id = br_ssl_choose_hash(
br_ssl_server_get_client_hashes(cc));
fh = (hash_id != 0);
}
choices->chain = pc->chain;
choices->chain_len = pc->chain_len;
for (u = 0; u < st_num; u ++) {
unsigned tt;
tt = st[u][1];
switch (tt >> 12) {
case BR_SSLKEYX_RSA:
if ((pc->allowed_usages & BR_KEYTYPE_KEYX) != 0) {
choices->cipher_suite = st[u][0];
return 1;
}
break;
case BR_SSLKEYX_ECDHE_RSA:
if ((pc->allowed_usages & BR_KEYTYPE_SIGN) != 0 && fh) {
choices->cipher_suite = st[u][0];
choices->algo_id = hash_id + 0xFF00;
return 1;
}
break;
}
}
return 0;
}
static uint32_t
sr_do_keyx(const br_ssl_server_policy_class **pctx,
unsigned char *data, size_t *len)
{
br_ssl_server_policy_rsa_context *pc;
pc = (br_ssl_server_policy_rsa_context *)pctx;
return br_rsa_ssl_decrypt(pc->irsacore, pc->sk, data, *len);
}
/*
* OID for hash functions in RSA signatures.
*/
static const unsigned char HASH_OID_SHA1[] = {
0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A
};
static const unsigned char HASH_OID_SHA224[] = {
0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04
};
static const unsigned char HASH_OID_SHA256[] = {
0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01
};
static const unsigned char HASH_OID_SHA384[] = {
0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02
};
static const unsigned char HASH_OID_SHA512[] = {
0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03
};
static const unsigned char *HASH_OID[] = {
HASH_OID_SHA1,
HASH_OID_SHA224,
HASH_OID_SHA256,
HASH_OID_SHA384,
HASH_OID_SHA512
};
static size_t
sr_do_sign(const br_ssl_server_policy_class **pctx,
unsigned algo_id, unsigned char *data, size_t hv_len, size_t len)
{
br_ssl_server_policy_rsa_context *pc;
unsigned char hv[64];
size_t sig_len;
const unsigned char *hash_oid;
pc = (br_ssl_server_policy_rsa_context *)pctx;
memcpy(hv, data, hv_len);
algo_id &= 0xFF;
if (algo_id == 0) {
hash_oid = NULL;
} else if (algo_id >= 2 && algo_id <= 6) {
hash_oid = HASH_OID[algo_id - 2];
} else {
return 0;
}
sig_len = (pc->sk->n_bitlen + 7) >> 3;
if (len < sig_len) {
return 0;
}
return pc->irsasign(hash_oid, hv, hv_len, pc->sk, data) ? sig_len : 0;
}
static const br_ssl_server_policy_class sr_policy_vtable = {
sizeof(br_ssl_server_policy_rsa_context),
sr_choose,
sr_do_keyx,
sr_do_sign
};
/* see bearssl_ssl.h */
void
br_ssl_server_set_single_rsa(br_ssl_server_context *cc,
const br_x509_certificate *chain, size_t chain_len,
const br_rsa_private_key *sk, unsigned allowed_usages,
br_rsa_private irsacore, br_rsa_pkcs1_sign irsasign)
{
cc->chain_handler.single_rsa.vtable = &sr_policy_vtable;
cc->chain_handler.single_rsa.chain = chain;
cc->chain_handler.single_rsa.chain_len = chain_len;
cc->chain_handler.single_rsa.sk = sk;
cc->chain_handler.single_rsa.allowed_usages = allowed_usages;
cc->chain_handler.single_rsa.irsacore = irsacore;
cc->chain_handler.single_rsa.irsasign = irsasign;
cc->policy_vtable = &cc->chain_handler.single_rsa.vtable;
}

View File

@ -1,252 +0,0 @@
/*
* Copyright (c) 2017 Thomas Pornin <pornin@bolet.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#define BR_ENABLE_INTRINSICS 1
#include "inner.h"
#if BR_USE_GETENTROPY
#include <unistd.h>
#endif
#if BR_USE_URANDOM
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#endif
#if BR_USE_WIN32_RAND
#include <windows.h>
#include <wincrypt.h>
#pragma comment(lib, "advapi32")
#endif
/*
* Seeder that uses the RDRAND opcodes (on x86 CPU).
*/
#if BR_RDRAND
BR_TARGETS_X86_UP
BR_TARGET("rdrnd")
static int
seeder_rdrand(const br_prng_class **ctx)
{
unsigned char tmp[32];
size_t u;
for (u = 0; u < sizeof tmp; u += sizeof(uint32_t)) {
int j;
uint32_t x;
/*
* We use the 32-bit intrinsic so that code is compatible
* with both 32-bit and 64-bit architectures.
*
* Intel recommends trying at least 10 times in case of
* failure.
*
* AMD bug: there are reports that some AMD processors
* have a bug that makes them fail silently after a
* suspend/resume cycle, in which case RDRAND will report
* a success but always return 0xFFFFFFFF.
* see: https://bugzilla.kernel.org/show_bug.cgi?id=85911
*
* As a mitigation, if the 32-bit value is 0 or -1, then
* it is considered a failure and tried again. This should
* reliably detect the buggy case, at least. This also
* implies that the selected seed values can never be
* 0x00000000 or 0xFFFFFFFF, which is not a problem since
* we are generating a seed for a PRNG, and we overdo it
* a bit (we generate 32 bytes of randomness, and 256 bits
* of entropy are really overkill).
*/
for (j = 0; j < 10; j ++) {
if (_rdrand32_step(&x) && x != 0 && x != (uint32_t)-1) {
goto next_word;
}
}
return 0;
next_word:
br_enc32le(tmp + u, x);
}
(*ctx)->update(ctx, tmp, sizeof tmp);
return 1;
}
BR_TARGETS_X86_DOWN
static int
rdrand_supported(void)
{
/*
* The RDRND support is bit 30 of ECX, as returned by CPUID.
*/
return br_cpuid(0, 0, 0x40000000, 0);
}
#endif
/*
* Seeder that uses /dev/urandom (on Unix-like systems).
*/
#if BR_USE_URANDOM
static int
seeder_urandom(const br_prng_class **ctx)
{
int f;
f = open("/dev/urandom", O_RDONLY);
if (f >= 0) {
unsigned char tmp[32];
size_t u;
for (u = 0; u < sizeof tmp;) {
ssize_t len;
len = read(f, tmp + u, (sizeof tmp) - u);
if (len < 0) {
if (errno == EINTR) {
continue;
}
break;
}
u += (size_t)len;
}
close(f);
if (u == sizeof tmp) {
(*ctx)->update(ctx, tmp, sizeof tmp);
return 1;
}
}
return 0;
}
#endif
/*
* Seeder that uses getentropy() (backed by getrandom() on some systems,
* e.g. Linux). On failure, it will use the /dev/urandom seeder (if
* enabled).
*/
#if BR_USE_GETENTROPY
static int
seeder_getentropy(const br_prng_class **ctx)
{
unsigned char tmp[32];
if (getentropy(tmp, sizeof tmp) == 0) {
(*ctx)->update(ctx, tmp, sizeof tmp);
return 1;
}
#if BR_USE_URANDOM
return seeder_urandom(ctx);
#else
return 0;
#endif
}
#endif
/*
* Seeder that uses CryptGenRandom() (on Windows).
*/
#if BR_USE_WIN32_RAND
static int
seeder_win32(const br_prng_class **ctx)
{
HCRYPTPROV hp;
if (CryptAcquireContext(&hp, 0, 0, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
{
BYTE buf[32];
BOOL r;
r = CryptGenRandom(hp, sizeof buf, buf);
CryptReleaseContext(hp, 0);
if (r) {
(*ctx)->update(ctx, buf, sizeof buf);
return 1;
}
}
return 0;
}
#endif
/*
* An aggregate seeder that uses RDRAND, and falls back to an OS-provided
* source if RDRAND fails.
*/
#if BR_RDRAND && (BR_USE_GETENTROPY || BR_USE_URANDOM || BR_USE_WIN32_RAND)
static int
seeder_rdrand_with_fallback(const br_prng_class **ctx)
{
if (!seeder_rdrand(ctx)) {
#if BR_USE_GETENTROPY
return seeder_getentropy(ctx);
#elif BR_USE_URANDOM
return seeder_urandom(ctx);
#elif BR_USE_WIN32_RAND
return seeder_win32(ctx);
#else
#error "macro selection has gone wrong"
#endif
}
return 1;
}
#endif
/* see bearssl_rand.h */
br_prng_seeder
br_prng_seeder_system(const char **name)
{
#if BR_RDRAND
if (rdrand_supported()) {
if (name != NULL) {
*name = "rdrand";
}
#if BR_USE_GETENTROPY || BR_USE_URANDOM || BR_USE_WIN32_RAND
return &seeder_rdrand_with_fallback;
#else
return &seeder_rdrand;
#endif
}
#endif
#if BR_USE_GETENTROPY
if (name != NULL) {
*name = "getentropy";
}
return &seeder_getentropy;
#elif BR_USE_URANDOM
if (name != NULL) {
*name = "urandom";
}
return &seeder_urandom;
#elif BR_USE_WIN32_RAND
if (name != NULL) {
*name = "win32";
}
return &seeder_win32;
#else
if (name != NULL) {
*name = "none";
}
return 0;
#endif
}