mirror of
https://github.com/xcat2/xNBA.git
synced 2025-04-27 07:15:54 +00:00
[crypto] Upgrade AES and RSA code to upstream axTLS version 1.4.5
All axTLS files are now vanilla versions of the upstream axTLS files, with one minor exception: the unused "ctx" parameter of bi_int_divide() has been marked with "__unused" to avoid a compilation error. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
parent
74b1e706a8
commit
1c29b4d979
@ -1,23 +1,33 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
* Copyright (c) 2007, Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of the axTLS project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
/**
|
||||
* AES implementation - this is a small code version. There are much faster
|
||||
* versions around but they are much larger in size (i.e. they use large
|
||||
@ -25,6 +35,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "os_port.h"
|
||||
#include "crypto.h"
|
||||
|
||||
/* all commented out in skeleton mode */
|
||||
@ -64,10 +75,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
(f8)^=rot2(f4), \
|
||||
(f8)^rot1(f9))
|
||||
|
||||
/* some macros to do endian independent byte extraction */
|
||||
#define n2l(c,l) l=ntohl(*c); c++
|
||||
#define l2n(l,c) *c++=htonl(l)
|
||||
|
||||
/*
|
||||
* AES S-box
|
||||
*/
|
||||
@ -154,11 +161,15 @@ static const unsigned char Rcon[30]=
|
||||
0xb3,0x7d,0xfa,0xef,0xc5,0x91,
|
||||
};
|
||||
|
||||
/* ----- static functions ----- */
|
||||
static void AES_encrypt(const AES_CTX *ctx, uint32_t *data);
|
||||
static void AES_decrypt(const AES_CTX *ctx, uint32_t *data);
|
||||
|
||||
/* Perform doubling in Galois Field GF(2^8) using the irreducible polynomial
|
||||
x^8+x^4+x^3+x+1 */
|
||||
static unsigned char AES_xtime(uint32_t x)
|
||||
{
|
||||
return x = (x&0x80) ? (x<<1)^0x1b : x<<1;
|
||||
return (x&0x80) ? (x<<1)^0x1b : x<<1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -247,7 +258,7 @@ void AES_convert_key(AES_CTX *ctx)
|
||||
k = ctx->ks;
|
||||
k += 4;
|
||||
|
||||
for (i=ctx->rounds*4; i>4; i--)
|
||||
for (i= ctx->rounds*4; i > 4; i--)
|
||||
{
|
||||
w= *k;
|
||||
w = inv_mix_col(w,t1,t2,t3,t4);
|
||||
@ -255,52 +266,43 @@ void AES_convert_key(AES_CTX *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Encrypt a byte sequence (with a block size 16) using the AES cipher.
|
||||
*/
|
||||
void AES_cbc_encrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
|
||||
{
|
||||
uint32_t tin0, tin1, tin2, tin3;
|
||||
uint32_t tout0, tout1, tout2, tout3;
|
||||
uint32_t tin[4];
|
||||
uint32_t *iv = (uint32_t *)ctx->iv;
|
||||
uint32_t *msg_32 = (uint32_t *)msg;
|
||||
uint32_t *out_32 = (uint32_t *)out;
|
||||
int i;
|
||||
uint32_t tin[4], tout[4], iv[4];
|
||||
|
||||
n2l(iv, tout0);
|
||||
n2l(iv, tout1);
|
||||
n2l(iv, tout2);
|
||||
n2l(iv, tout3);
|
||||
iv -= 4;
|
||||
memcpy(iv, ctx->iv, AES_IV_SIZE);
|
||||
for (i = 0; i < 4; i++)
|
||||
tout[i] = ntohl(iv[i]);
|
||||
|
||||
for (length -= 16; length >= 0; length -= 16)
|
||||
for (length -= AES_BLOCKSIZE; length >= 0; length -= AES_BLOCKSIZE)
|
||||
{
|
||||
n2l(msg_32, tin0);
|
||||
n2l(msg_32, tin1);
|
||||
n2l(msg_32, tin2);
|
||||
n2l(msg_32, tin3);
|
||||
tin[0] = tin0^tout0;
|
||||
tin[1] = tin1^tout1;
|
||||
tin[2] = tin2^tout2;
|
||||
tin[3] = tin3^tout3;
|
||||
uint32_t msg_32[4];
|
||||
uint32_t out_32[4];
|
||||
memcpy(msg_32, msg, AES_BLOCKSIZE);
|
||||
msg += AES_BLOCKSIZE;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
tin[i] = ntohl(msg_32[i])^tout[i];
|
||||
|
||||
AES_encrypt(ctx, tin);
|
||||
|
||||
tout0 = tin[0];
|
||||
l2n(tout0, out_32);
|
||||
tout1 = tin[1];
|
||||
l2n(tout1, out_32);
|
||||
tout2 = tin[2];
|
||||
l2n(tout2, out_32);
|
||||
tout3 = tin[3];
|
||||
l2n(tout3, out_32);
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
tout[i] = tin[i];
|
||||
out_32[i] = htonl(tout[i]);
|
||||
}
|
||||
|
||||
memcpy(out, out_32, AES_BLOCKSIZE);
|
||||
out += AES_BLOCKSIZE;
|
||||
}
|
||||
|
||||
l2n(tout0, iv);
|
||||
l2n(tout1, iv);
|
||||
l2n(tout2, iv);
|
||||
l2n(tout3, iv);
|
||||
for (i = 0; i < 4; i++)
|
||||
iv[i] = htonl(tout[i]);
|
||||
memcpy(ctx->iv, iv, AES_IV_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -308,61 +310,48 @@ void AES_cbc_encrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
|
||||
*/
|
||||
void AES_cbc_decrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
|
||||
{
|
||||
uint32_t tin0, tin1, tin2, tin3;
|
||||
uint32_t xor0,xor1,xor2,xor3;
|
||||
uint32_t tout0,tout1,tout2,tout3;
|
||||
uint32_t data[4];
|
||||
uint32_t *iv = (uint32_t *)ctx->iv;
|
||||
uint32_t *msg_32 = (uint32_t *)msg;
|
||||
uint32_t *out_32 = (uint32_t *)out;
|
||||
int i;
|
||||
uint32_t tin[4], xor[4], tout[4], data[4], iv[4];
|
||||
|
||||
n2l(iv ,xor0);
|
||||
n2l(iv, xor1);
|
||||
n2l(iv, xor2);
|
||||
n2l(iv, xor3);
|
||||
iv -= 4;
|
||||
memcpy(iv, ctx->iv, AES_IV_SIZE);
|
||||
for (i = 0; i < 4; i++)
|
||||
xor[i] = ntohl(iv[i]);
|
||||
|
||||
for (length-=16; length >= 0; length -= 16)
|
||||
for (length -= 16; length >= 0; length -= 16)
|
||||
{
|
||||
n2l(msg_32, tin0);
|
||||
n2l(msg_32, tin1);
|
||||
n2l(msg_32, tin2);
|
||||
n2l(msg_32, tin3);
|
||||
uint32_t msg_32[4];
|
||||
uint32_t out_32[4];
|
||||
memcpy(msg_32, msg, AES_BLOCKSIZE);
|
||||
msg += AES_BLOCKSIZE;
|
||||
|
||||
data[0] = tin0;
|
||||
data[1] = tin1;
|
||||
data[2] = tin2;
|
||||
data[3] = tin3;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
tin[i] = ntohl(msg_32[i]);
|
||||
data[i] = tin[i];
|
||||
}
|
||||
|
||||
AES_decrypt(ctx, data);
|
||||
|
||||
tout0 = data[0]^xor0;
|
||||
tout1 = data[1]^xor1;
|
||||
tout2 = data[2]^xor2;
|
||||
tout3 = data[3]^xor3;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
tout[i] = data[i]^xor[i];
|
||||
xor[i] = tin[i];
|
||||
out_32[i] = htonl(tout[i]);
|
||||
}
|
||||
|
||||
xor0 = tin0;
|
||||
xor1 = tin1;
|
||||
xor2 = tin2;
|
||||
xor3 = tin3;
|
||||
|
||||
l2n(tout0, out_32);
|
||||
l2n(tout1, out_32);
|
||||
l2n(tout2, out_32);
|
||||
l2n(tout3, out_32);
|
||||
memcpy(out, out_32, AES_BLOCKSIZE);
|
||||
out += AES_BLOCKSIZE;
|
||||
}
|
||||
|
||||
l2n(xor0, iv);
|
||||
l2n(xor1, iv);
|
||||
l2n(xor2, iv);
|
||||
l2n(xor3, iv);
|
||||
for (i = 0; i < 4; i++)
|
||||
iv[i] = htonl(xor[i]);
|
||||
memcpy(ctx->iv, iv, AES_IV_SIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Encrypt a single block (16 bytes) of data
|
||||
*/
|
||||
void AES_encrypt(const AES_CTX *ctx, uint32_t *data)
|
||||
static void AES_encrypt(const AES_CTX *ctx, uint32_t *data)
|
||||
{
|
||||
/* To make this code smaller, generate the sbox entries on the fly.
|
||||
* This will have a really heavy effect upon performance.
|
||||
@ -375,9 +364,7 @@ void AES_encrypt(const AES_CTX *ctx, uint32_t *data)
|
||||
|
||||
/* Pre-round key addition */
|
||||
for (row = 0; row < 4; row++)
|
||||
{
|
||||
data[row] ^= *(k++);
|
||||
}
|
||||
|
||||
/* Encrypt one block. */
|
||||
for (curr_rnd = 0; curr_rnd < rounds; curr_rnd++)
|
||||
@ -395,12 +382,10 @@ void AES_encrypt(const AES_CTX *ctx, uint32_t *data)
|
||||
{
|
||||
tmp1 = a0 ^ a1 ^ a2 ^ a3;
|
||||
old_a0 = a0;
|
||||
|
||||
a0 ^= tmp1 ^ AES_xtime(a0 ^ a1);
|
||||
a1 ^= tmp1 ^ AES_xtime(a1 ^ a2);
|
||||
a2 ^= tmp1 ^ AES_xtime(a2 ^ a3);
|
||||
a3 ^= tmp1 ^ AES_xtime(a3 ^ old_a0);
|
||||
|
||||
}
|
||||
|
||||
tmp[row] = ((a0 << 24) | (a1 << 16) | (a2 << 8) | a3);
|
||||
@ -409,32 +394,28 @@ void AES_encrypt(const AES_CTX *ctx, uint32_t *data)
|
||||
/* KeyAddition - note that it is vital that this loop is separate from
|
||||
the MixColumn operation, which must be atomic...*/
|
||||
for (row = 0; row < 4; row++)
|
||||
{
|
||||
data[row] = tmp[row] ^ *(k++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt a single block (16 bytes) of data
|
||||
*/
|
||||
void AES_decrypt(const AES_CTX *ctx, uint32_t *data)
|
||||
static void AES_decrypt(const AES_CTX *ctx, uint32_t *data)
|
||||
{
|
||||
uint32_t tmp[4];
|
||||
uint32_t xt0,xt1,xt2,xt3,xt4,xt5,xt6;
|
||||
uint32_t a0, a1, a2, a3, row;
|
||||
int curr_rnd;
|
||||
int rounds = ctx->rounds;
|
||||
uint32_t *k = (uint32_t*)ctx->ks + ((rounds+1)*4);
|
||||
const uint32_t *k = ctx->ks + ((rounds+1)*4);
|
||||
|
||||
/* pre-round key addition */
|
||||
for (row=4; row > 0;row--)
|
||||
{
|
||||
data[row-1] ^= *(--k);
|
||||
}
|
||||
|
||||
/* Decrypt one block */
|
||||
for (curr_rnd=0; curr_rnd < rounds; curr_rnd++)
|
||||
for (curr_rnd = 0; curr_rnd < rounds; curr_rnd++)
|
||||
{
|
||||
/* Perform ByteSub and ShiftRow operations together */
|
||||
for (row = 4; row > 0; row--)
|
||||
@ -469,9 +450,7 @@ void AES_decrypt(const AES_CTX *ctx, uint32_t *data)
|
||||
}
|
||||
|
||||
for (row = 4; row > 0; row--)
|
||||
{
|
||||
data[row-1] = tmp[row-1] ^ *(--k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,31 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
* Copyright (c) 2007, Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of the axTLS project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -53,12 +65,17 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "os_port.h"
|
||||
#include "bigint.h"
|
||||
#include "crypto.h"
|
||||
|
||||
#define V1 v->comps[v->size-1] /**< v1 for division */
|
||||
#define V2 v->comps[v->size-2] /**< v2 for division */
|
||||
#define U(j) tmp_u->comps[tmp_u->size-j-1] /**< uj for division */
|
||||
#define Q(j) quotient->comps[quotient->size-j-1] /**< qj for division */
|
||||
|
||||
static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bi, comp i);
|
||||
static bigint *bi_int_divide(BI_CTX *ctx, bigint *biR, comp denom);
|
||||
static bigint __malloc *alloc(BI_CTX *ctx, int size);
|
||||
static bigint *alloc(BI_CTX *ctx, int size);
|
||||
static bigint *trim(bigint *bi);
|
||||
static void more_comps(bigint *bi, int n);
|
||||
#if defined(CONFIG_BIGINT_KARATSUBA) || defined(CONFIG_BIGINT_BARRETT) || \
|
||||
@ -69,8 +86,11 @@ static bigint *comp_left_shift(bigint *biR, int num_shifts);
|
||||
|
||||
#ifdef CONFIG_BIGINT_CHECK_ON
|
||||
static void check(const bigint *bi);
|
||||
#else
|
||||
#define check(A) /**< disappears in normal production mode */
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Start a new bigint context.
|
||||
* @return A bigint context.
|
||||
@ -97,8 +117,6 @@ BI_CTX *bi_initialize(void)
|
||||
*/
|
||||
void bi_terminate(BI_CTX *ctx)
|
||||
{
|
||||
bigint *p, *pn;
|
||||
|
||||
bi_depermanent(ctx->bi_radix);
|
||||
bi_free(ctx, ctx->bi_radix);
|
||||
|
||||
@ -111,6 +129,20 @@ void bi_terminate(BI_CTX *ctx)
|
||||
abort();
|
||||
}
|
||||
|
||||
bi_clear_cache(ctx);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
*@brief Clear the memory cache.
|
||||
*/
|
||||
void bi_clear_cache(BI_CTX *ctx)
|
||||
{
|
||||
bigint *p, *pn;
|
||||
|
||||
if (ctx->free_list == NULL)
|
||||
return;
|
||||
|
||||
for (p = ctx->free_list; p != NULL; p = pn)
|
||||
{
|
||||
pn = p->next;
|
||||
@ -118,7 +150,8 @@ void bi_terminate(BI_CTX *ctx)
|
||||
free(p);
|
||||
}
|
||||
|
||||
free(ctx);
|
||||
ctx->free_count = 0;
|
||||
ctx->free_list = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -410,18 +443,18 @@ bigint *bi_divide(BI_CTX *ctx, bigint *u, bigint *v, int is_mod)
|
||||
else
|
||||
{
|
||||
q_dash = (comp)(((long_comp)U(0)*COMP_RADIX + U(1))/V1);
|
||||
}
|
||||
|
||||
if (v->size > 1 && V2)
|
||||
{
|
||||
/* we are implementing the following:
|
||||
if (V2*q_dash > (((U(0)*COMP_RADIX + U(1) -
|
||||
q_dash*V1)*COMP_RADIX) + U(2))) ... */
|
||||
comp inner = (comp)((long_comp)COMP_RADIX*U(0) + U(1) -
|
||||
(long_comp)q_dash*V1);
|
||||
if ((long_comp)V2*q_dash > (long_comp)inner*COMP_RADIX + U(2))
|
||||
if (v->size > 1 && V2)
|
||||
{
|
||||
q_dash--;
|
||||
/* we are implementing the following:
|
||||
if (V2*q_dash > (((U(0)*COMP_RADIX + U(1) -
|
||||
q_dash*V1)*COMP_RADIX) + U(2))) ... */
|
||||
comp inner = (comp)((long_comp)COMP_RADIX*U(0) + U(1) -
|
||||
(long_comp)q_dash*V1);
|
||||
if ((long_comp)V2*q_dash > (long_comp)inner*COMP_RADIX + U(2))
|
||||
{
|
||||
q_dash--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -473,6 +506,7 @@ bigint *bi_divide(BI_CTX *ctx, bigint *u, bigint *v, int is_mod)
|
||||
/*
|
||||
* Perform an integer divide on a bigint.
|
||||
*/
|
||||
// mcb30 - mark ctx with __unused to avoid a compilation error
|
||||
static bigint *bi_int_divide(BI_CTX *ctx __unused, bigint *biR, comp denom)
|
||||
{
|
||||
int i = biR->size - 1;
|
||||
@ -485,7 +519,7 @@ static bigint *bi_int_divide(BI_CTX *ctx __unused, bigint *biR, comp denom)
|
||||
r = (r<<COMP_BIT_SIZE) + biR->comps[i];
|
||||
biR->comps[i] = (comp)(r / denom);
|
||||
r %= denom;
|
||||
} while (--i != 0);
|
||||
} while (--i >= 0);
|
||||
|
||||
return trim(biR);
|
||||
}
|
||||
@ -690,10 +724,11 @@ void bi_export(BI_CTX *ctx, bigint *x, uint8_t *data, int size)
|
||||
|
||||
if (k < 0)
|
||||
{
|
||||
break;
|
||||
goto buf_done;
|
||||
}
|
||||
}
|
||||
}
|
||||
buf_done:
|
||||
|
||||
bi_free(ctx, x);
|
||||
}
|
||||
@ -769,11 +804,16 @@ void bi_free_mod(BI_CTX *ctx, int mod_offset)
|
||||
|
||||
/**
|
||||
* Perform a standard multiplication between two bigints.
|
||||
*
|
||||
* Barrett reduction has no need for some parts of the product, so ignore bits
|
||||
* of the multiply. This routine gives Barrett its big performance
|
||||
* improvements over Classical/Montgomery reduction methods.
|
||||
*/
|
||||
static bigint *regular_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
|
||||
static bigint *regular_multiply(BI_CTX *ctx, bigint *bia, bigint *bib,
|
||||
int inner_partial, int outer_partial)
|
||||
{
|
||||
int i, j, i_plus_j;
|
||||
int n = bia->size;
|
||||
int i = 0, j;
|
||||
int n = bia->size;
|
||||
int t = bib->size;
|
||||
bigint *biR = alloc(ctx, n + t);
|
||||
comp *sr = biR->comps;
|
||||
@ -785,23 +825,33 @@ static bigint *regular_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
|
||||
|
||||
/* clear things to start with */
|
||||
memset(biR->comps, 0, ((n+t)*COMP_BYTE_SIZE));
|
||||
i = 0;
|
||||
|
||||
do
|
||||
{
|
||||
long_comp tmp;
|
||||
comp carry = 0;
|
||||
comp b = *sb++;
|
||||
i_plus_j = i;
|
||||
int r_index = i;
|
||||
j = 0;
|
||||
|
||||
if (outer_partial && outer_partial-i > 0 && outer_partial < n)
|
||||
{
|
||||
r_index = outer_partial-1;
|
||||
j = outer_partial-i-1;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
long_comp tmp = sr[i_plus_j] + (long_comp)sa[j]*b + carry;
|
||||
sr[i_plus_j++] = (comp)tmp; /* downsize */
|
||||
carry = (comp)(tmp >> COMP_BIT_SIZE);
|
||||
if (inner_partial && r_index >= inner_partial)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = sr[r_index] + ((long_comp)sa[j])*sb[i] + carry;
|
||||
sr[r_index++] = (comp)tmp; /* downsize */
|
||||
carry = tmp >> COMP_BIT_SIZE;
|
||||
} while (++j < n);
|
||||
|
||||
sr[i_plus_j] = carry;
|
||||
sr[r_index] = carry;
|
||||
} while (++i < t);
|
||||
|
||||
bi_free(ctx, bia);
|
||||
@ -881,12 +931,12 @@ bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
|
||||
#ifdef CONFIG_BIGINT_KARATSUBA
|
||||
if (min(bia->size, bib->size) < MUL_KARATSUBA_THRESH)
|
||||
{
|
||||
return regular_multiply(ctx, bia, bib);
|
||||
return regular_multiply(ctx, bia, bib, 0, 0);
|
||||
}
|
||||
|
||||
return karatsuba(ctx, bia, bib, 0);
|
||||
#else
|
||||
return regular_multiply(ctx, bia, bib);
|
||||
return regular_multiply(ctx, bia, bib, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -898,47 +948,46 @@ static bigint *regular_square(BI_CTX *ctx, bigint *bi)
|
||||
{
|
||||
int t = bi->size;
|
||||
int i = 0, j;
|
||||
bigint *biR = alloc(ctx, t*2);
|
||||
bigint *biR = alloc(ctx, t*2+1);
|
||||
comp *w = biR->comps;
|
||||
comp *x = bi->comps;
|
||||
comp carry;
|
||||
|
||||
long_comp carry;
|
||||
memset(w, 0, biR->size*COMP_BYTE_SIZE);
|
||||
|
||||
do
|
||||
{
|
||||
long_comp tmp = w[2*i] + (long_comp)x[i]*x[i];
|
||||
comp u = 0;
|
||||
w[2*i] = (comp)tmp;
|
||||
carry = (comp)(tmp >> COMP_BIT_SIZE);
|
||||
carry = tmp >> COMP_BIT_SIZE;
|
||||
|
||||
for (j = i+1; j < t; j++)
|
||||
{
|
||||
uint8_t c = 0;
|
||||
long_comp xx = (long_comp)x[i]*x[j];
|
||||
long_comp blob = (long_comp)w[i+j]+carry;
|
||||
if ((COMP_MAX-xx) < xx)
|
||||
c = 1;
|
||||
|
||||
if (u) /* previous overflow */
|
||||
{
|
||||
blob += COMP_RADIX;
|
||||
}
|
||||
tmp = (xx<<1);
|
||||
|
||||
u = 0;
|
||||
if (xx & COMP_BIG_MSB) /* check for overflow */
|
||||
{
|
||||
u = 1;
|
||||
}
|
||||
if ((COMP_MAX-tmp) < w[i+j])
|
||||
c = 1;
|
||||
|
||||
tmp = 2*xx + blob;
|
||||
tmp += w[i+j];
|
||||
|
||||
if ((COMP_MAX-tmp) < carry)
|
||||
c = 1;
|
||||
|
||||
tmp += carry;
|
||||
w[i+j] = (comp)tmp;
|
||||
carry = (comp)(tmp >> COMP_BIT_SIZE);
|
||||
carry = tmp >> COMP_BIT_SIZE;
|
||||
|
||||
if (c)
|
||||
carry += COMP_RADIX;
|
||||
}
|
||||
|
||||
w[i+t] += carry;
|
||||
|
||||
if (u)
|
||||
{
|
||||
w[i+t+1] = 1; /* add carry */
|
||||
}
|
||||
tmp = w[i+t] + carry;
|
||||
w[i+t] = (comp)tmp;
|
||||
w[i+t+1] = tmp >> COMP_BIT_SIZE;
|
||||
} while (++i < t);
|
||||
|
||||
bi_free(ctx, bi);
|
||||
@ -1092,7 +1141,7 @@ static int find_max_exp_index(bigint *biexp)
|
||||
}
|
||||
|
||||
shift >>= 1;
|
||||
} while (--i != 0);
|
||||
} while (i-- != 0);
|
||||
|
||||
return -1; /* error - must have been a leading 0 */
|
||||
}
|
||||
@ -1115,7 +1164,7 @@ static int exp_bit_is_one(bigint *biexp, int offset)
|
||||
shift <<= 1;
|
||||
}
|
||||
|
||||
return test & shift;
|
||||
return (test & shift) != 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BIGINT_CHECK_ON
|
||||
@ -1210,81 +1259,6 @@ static bigint *comp_mod(bigint *bi, int mod)
|
||||
return bi;
|
||||
}
|
||||
|
||||
/*
|
||||
* Barrett reduction has no need for some parts of the product, so ignore bits
|
||||
* of the multiply. This routine gives Barrett its big performance
|
||||
* improvements over Classical/Montgomery reduction methods.
|
||||
*/
|
||||
static bigint *partial_multiply(BI_CTX *ctx, bigint *bia, bigint *bib,
|
||||
int inner_partial, int outer_partial)
|
||||
{
|
||||
int i = 0, j, n = bia->size, t = bib->size;
|
||||
bigint *biR;
|
||||
comp carry;
|
||||
comp *sr, *sa, *sb;
|
||||
|
||||
check(bia);
|
||||
check(bib);
|
||||
|
||||
biR = alloc(ctx, n + t);
|
||||
sa = bia->comps;
|
||||
sb = bib->comps;
|
||||
sr = biR->comps;
|
||||
|
||||
if (inner_partial)
|
||||
{
|
||||
memset(sr, 0, inner_partial*COMP_BYTE_SIZE);
|
||||
}
|
||||
else /* outer partial */
|
||||
{
|
||||
if (n < outer_partial || t < outer_partial) /* should we bother? */
|
||||
{
|
||||
bi_free(ctx, bia);
|
||||
bi_free(ctx, bib);
|
||||
biR->comps[0] = 0; /* return 0 */
|
||||
biR->size = 1;
|
||||
return biR;
|
||||
}
|
||||
|
||||
memset(&sr[outer_partial], 0, (n+t-outer_partial)*COMP_BYTE_SIZE);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
comp *a = sa;
|
||||
comp b = *sb++;
|
||||
long_comp tmp;
|
||||
int i_plus_j = i;
|
||||
carry = 0;
|
||||
j = n;
|
||||
|
||||
if (outer_partial && i_plus_j < outer_partial)
|
||||
{
|
||||
i_plus_j = outer_partial;
|
||||
a = &sa[outer_partial-i];
|
||||
j = n-(outer_partial-i);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (inner_partial && i_plus_j >= inner_partial)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = sr[i_plus_j] + ((long_comp)*a++)*b + carry;
|
||||
sr[i_plus_j++] = (comp)tmp; /* downsize */
|
||||
carry = (comp)(tmp >> COMP_BIT_SIZE);
|
||||
} while (--j != 0);
|
||||
|
||||
sr[i_plus_j] = carry;
|
||||
} while (++i < t);
|
||||
|
||||
bi_free(ctx, bia);
|
||||
bi_free(ctx, bib);
|
||||
return trim(biR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Perform a single Barrett reduction.
|
||||
* @param ctx [in] The bigint session context.
|
||||
@ -1310,12 +1284,12 @@ bigint *bi_barrett(BI_CTX *ctx, bigint *bi)
|
||||
q1 = comp_right_shift(bi_clone(ctx, bi), k-1);
|
||||
|
||||
/* do outer partial multiply */
|
||||
q2 = partial_multiply(ctx, q1, ctx->bi_mu[mod_offset], 0, k-1);
|
||||
q2 = regular_multiply(ctx, q1, ctx->bi_mu[mod_offset], 0, k-1);
|
||||
q3 = comp_right_shift(q2, k+1);
|
||||
r1 = comp_mod(bi, k+1);
|
||||
|
||||
/* do inner partial multiply */
|
||||
r2 = comp_mod(partial_multiply(ctx, q3, bim, k+1, 0), k+1);
|
||||
r2 = comp_mod(regular_multiply(ctx, q3, bim, k+1, 0), k+1);
|
||||
r = bi_subtract(ctx, r1, r2, NULL);
|
||||
|
||||
/* if (r >= m) r = r - m; */
|
||||
@ -1366,6 +1340,7 @@ static void precompute_slide_window(BI_CTX *ctx, int window, bigint *g1)
|
||||
* @param ctx [in] The bigint session context.
|
||||
* @param bi [in] The bigint on which to perform the mod power operation.
|
||||
* @param biexp [in] The bigint exponent.
|
||||
* @return The result of the mod exponentiation operation
|
||||
* @see bi_set_mod().
|
||||
*/
|
||||
bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp)
|
||||
@ -1467,6 +1442,7 @@ bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp)
|
||||
* @param bi [in] The bigint to perform the exp/mod.
|
||||
* @param bim [in] The temporary modulus.
|
||||
* @param biexp [in] The bigint exponent.
|
||||
* @return The result of the mod exponentiation operation
|
||||
* @see bi_set_mod().
|
||||
*/
|
||||
bigint *bi_mod_power2(BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp)
|
||||
@ -1493,4 +1469,45 @@ bigint *bi_mod_power2(BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp)
|
||||
return biR;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BIGINT_CRT
|
||||
/**
|
||||
* @brief Use the Chinese Remainder Theorem to quickly perform RSA decrypts.
|
||||
*
|
||||
* @param ctx [in] The bigint session context.
|
||||
* @param bi [in] The bigint to perform the exp/mod.
|
||||
* @param dP [in] CRT's dP bigint
|
||||
* @param dQ [in] CRT's dQ bigint
|
||||
* @param p [in] CRT's p bigint
|
||||
* @param q [in] CRT's q bigint
|
||||
* @param qInv [in] CRT's qInv bigint
|
||||
* @return The result of the CRT operation
|
||||
*/
|
||||
bigint *bi_crt(BI_CTX *ctx, bigint *bi,
|
||||
bigint *dP, bigint *dQ,
|
||||
bigint *p, bigint *q, bigint *qInv)
|
||||
{
|
||||
bigint *m1, *m2, *h;
|
||||
|
||||
/* Montgomery has a condition the 0 < x, y < m and these products violate
|
||||
* that condition. So disable Montgomery when using CRT */
|
||||
#if defined(CONFIG_BIGINT_MONTGOMERY)
|
||||
ctx->use_classical = 1;
|
||||
#endif
|
||||
ctx->mod_offset = BIGINT_P_OFFSET;
|
||||
m1 = bi_mod_power(ctx, bi_copy(bi), dP);
|
||||
|
||||
ctx->mod_offset = BIGINT_Q_OFFSET;
|
||||
m2 = bi_mod_power(ctx, bi, dQ);
|
||||
|
||||
h = bi_subtract(ctx, bi_add(ctx, m1, p), bi_copy(m2), NULL);
|
||||
h = bi_multiply(ctx, h, qInv);
|
||||
ctx->mod_offset = BIGINT_P_OFFSET;
|
||||
h = bi_residue(ctx, h);
|
||||
#if defined(CONFIG_BIGINT_MONTGOMERY)
|
||||
ctx->use_classical = 0; /* reset for any further operation */
|
||||
#endif
|
||||
return bi_add(ctx, m2, bi_multiply(ctx, q, h));
|
||||
}
|
||||
#endif
|
||||
/** @} */
|
||||
|
@ -1,44 +1,43 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
* Copyright (c) 2007, Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of the axTLS project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
#ifndef BIGINT_HEADER
|
||||
#define BIGINT_HEADER
|
||||
|
||||
/* enable features based on a 'super-set' capbaility. */
|
||||
#if defined(CONFIG_SSL_FULL_MODE)
|
||||
#define CONFIG_SSL_ENABLE_CLIENT
|
||||
#define CONFIG_SSL_CERT_VERIFICATION
|
||||
#elif defined(CONFIG_SSL_ENABLE_CLIENT)
|
||||
#define CONFIG_SSL_CERT_VERIFICATION
|
||||
#endif
|
||||
#include "crypto.h"
|
||||
|
||||
#include "os_port.h"
|
||||
#include "bigint_impl.h"
|
||||
|
||||
#ifndef CONFIG_BIGINT_CHECK_ON
|
||||
#define check(A) /**< disappears in normal production mode */
|
||||
#endif
|
||||
BI_CTX *bi_initialize(void);
|
||||
void bi_terminate(BI_CTX *ctx);
|
||||
void bi_permanent(bigint *bi);
|
||||
void bi_depermanent(bigint *bi);
|
||||
void bi_clear_cache(BI_CTX *ctx);
|
||||
void bi_free(BI_CTX *ctx, bigint *bi);
|
||||
bigint *bi_copy(bigint *bi);
|
||||
bigint *bi_clone(BI_CTX *ctx, const bigint *bi);
|
||||
@ -90,4 +89,11 @@ bigint *bi_square(BI_CTX *ctx, bigint *bi);
|
||||
#define bi_square(A, B) bi_multiply(A, bi_copy(B), B)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BIGINT_CRT
|
||||
bigint *bi_crt(BI_CTX *ctx, bigint *bi,
|
||||
bigint *dP, bigint *dQ,
|
||||
bigint *p, bigint *q,
|
||||
bigint *qInv);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,19 +1,31 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
* Copyright (c) 2007, Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of the axTLS project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef BIGINT_IMPL_HEADER
|
||||
@ -30,20 +42,39 @@
|
||||
#endif
|
||||
|
||||
/* Architecture specific functions for big ints */
|
||||
#if defined(CONFIG_INTEGER_8BIT)
|
||||
#define COMP_RADIX 256U /**< Max component + 1 */
|
||||
#define COMP_MAX 0xFFFFU/**< (Max dbl comp -1) */
|
||||
#define COMP_BIT_SIZE 8 /**< Number of bits in a component. */
|
||||
#define COMP_BYTE_SIZE 1 /**< Number of bytes in a component. */
|
||||
#define COMP_NUM_NIBBLES 2 /**< Used For diagnostics only. */
|
||||
typedef uint8_t comp; /**< A single precision component. */
|
||||
typedef uint16_t long_comp; /**< A double precision component. */
|
||||
typedef int16_t slong_comp; /**< A signed double precision component. */
|
||||
#elif defined(CONFIG_INTEGER_16BIT)
|
||||
#define COMP_RADIX 65536U /**< Max component + 1 */
|
||||
#define COMP_MAX 0xFFFFFFFFU/**< (Max dbl comp -1) */
|
||||
#define COMP_BIT_SIZE 16 /**< Number of bits in a component. */
|
||||
#define COMP_BYTE_SIZE 2 /**< Number of bytes in a component. */
|
||||
#define COMP_NUM_NIBBLES 4 /**< Used For diagnostics only. */
|
||||
typedef uint16_t comp; /**< A single precision component. */
|
||||
typedef uint32_t long_comp; /**< A double precision component. */
|
||||
typedef int32_t slong_comp; /**< A signed double precision component. */
|
||||
#else /* regular 32 bit */
|
||||
#ifdef WIN32
|
||||
#define COMP_RADIX 4294967296i64
|
||||
#define COMP_BIG_MSB 0x8000000000000000i64
|
||||
#define COMP_MAX 0xFFFFFFFFFFFFFFFFui64
|
||||
#else
|
||||
#define COMP_RADIX 4294967296ULL /**< Max component + 1 */
|
||||
#define COMP_BIG_MSB 0x8000000000000000ULL /**< (Max dbl comp + 1)/ 2 */
|
||||
#define COMP_MAX 0xFFFFFFFFFFFFFFFFULL/**< (Max dbl comp -1) */
|
||||
#endif
|
||||
#define COMP_BIT_SIZE 32 /**< Number of bits in a component. */
|
||||
#define COMP_BYTE_SIZE 4 /**< Number of bytes in a component. */
|
||||
#define COMP_NUM_NIBBLES 8 /**< Used For diagnostics only. */
|
||||
|
||||
typedef uint32_t comp; /**< A single precision component. */
|
||||
typedef uint64_t long_comp; /**< A double precision component. */
|
||||
typedef int64_t slong_comp; /**< A signed double precision component. */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @struct _bigint
|
||||
@ -97,9 +128,4 @@ typedef struct /**< A big integer "session" context. */
|
||||
|
||||
#define PERMANENT 0x7FFF55AA /**< A magic number for permanents. */
|
||||
|
||||
#define V1 v->comps[v->size-1] /**< v1 for division */
|
||||
#define V2 v->comps[v->size-2] /**< v2 for division */
|
||||
#define U(j) tmp_u->comps[tmp_u->size-j-1] /**< uj for division */
|
||||
#define Q(j) quotient->comps[quotient->size-j-1] /**< qj for division */
|
||||
|
||||
#endif
|
||||
|
13
src/crypto/axtls/config.h
Normal file
13
src/crypto/axtls/config.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef AXTLS_CONFIG_H
|
||||
#define AXTLS_CONFIG_H
|
||||
|
||||
/**
|
||||
* @file config.h
|
||||
*
|
||||
* Trick the axtls code into building within our build environment.
|
||||
*/
|
||||
|
||||
#define CONFIG_SSL_ENABLE_CLIENT 1
|
||||
#define CONFIG_BIGINT_CLASSICAL 1
|
||||
|
||||
#endif
|
@ -1,23 +1,33 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
* Copyright (c) 2007, Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of the axTLS project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
/**
|
||||
* @file crypto.h
|
||||
*/
|
||||
@ -29,20 +39,40 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include "bigint_impl.h"
|
||||
#include "bigint.h"
|
||||
|
||||
#ifndef STDCALL
|
||||
#define STDCALL
|
||||
#endif
|
||||
#ifndef EXP_FUNC
|
||||
#define EXP_FUNC
|
||||
#endif
|
||||
|
||||
|
||||
/* enable features based on a 'super-set' capbaility. */
|
||||
#if defined(CONFIG_SSL_FULL_MODE)
|
||||
#define CONFIG_SSL_ENABLE_CLIENT
|
||||
#define CONFIG_SSL_CERT_VERIFICATION
|
||||
#elif defined(CONFIG_SSL_ENABLE_CLIENT)
|
||||
#define CONFIG_SSL_CERT_VERIFICATION
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
* AES declarations
|
||||
**************************************************************************/
|
||||
|
||||
#define AES_MAXROUNDS 14
|
||||
#define AES_BLOCKSIZE 16
|
||||
#define AES_IV_SIZE 16
|
||||
|
||||
typedef struct aes_key_st
|
||||
{
|
||||
uint16_t rounds;
|
||||
uint16_t key_size;
|
||||
uint32_t ks[(AES_MAXROUNDS+1)*8];
|
||||
uint8_t iv[16];
|
||||
uint8_t iv[AES_IV_SIZE];
|
||||
} AES_CTX;
|
||||
|
||||
typedef enum
|
||||
@ -57,8 +87,6 @@ void AES_cbc_encrypt(AES_CTX *ctx, const uint8_t *msg,
|
||||
uint8_t *out, int length);
|
||||
void AES_cbc_decrypt(AES_CTX *ks, const uint8_t *in, uint8_t *out, int length);
|
||||
void AES_convert_key(AES_CTX *ctx);
|
||||
void AES_encrypt(const AES_CTX *ctx, uint32_t *data);
|
||||
void AES_decrypt(const AES_CTX *ctx, uint32_t *data);
|
||||
|
||||
/**************************************************************************
|
||||
* RC4 declarations
|
||||
@ -66,7 +94,7 @@ void AES_decrypt(const AES_CTX *ctx, uint32_t *data);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x, y, m[256];
|
||||
uint8_t x, y, m[256];
|
||||
} RC4_CTX;
|
||||
|
||||
void RC4_setup(RC4_CTX *s, const uint8_t *key, int length);
|
||||
@ -84,22 +112,38 @@ void RC4_crypt(RC4_CTX *s, const uint8_t *msg, uint8_t *data, int length);
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Intermediate_Hash[SHA1_SIZE/4]; /* Message Digest */
|
||||
uint32_t Length_Low; /* Message length in bits */
|
||||
uint32_t Length_High; /* Message length in bits */
|
||||
uint32_t Intermediate_Hash[SHA1_SIZE/4]; /* Message Digest */
|
||||
uint32_t Length_Low; /* Message length in bits */
|
||||
uint32_t Length_High; /* Message length in bits */
|
||||
uint16_t Message_Block_Index; /* Index into message block array */
|
||||
uint8_t Message_Block[64]; /* 512-bit message blocks */
|
||||
uint8_t Message_Block[64]; /* 512-bit message blocks */
|
||||
} SHA1_CTX;
|
||||
|
||||
void SHA1Init(SHA1_CTX *);
|
||||
void SHA1Update(SHA1_CTX *, const uint8_t * msg, int len);
|
||||
void SHA1Final(SHA1_CTX *, uint8_t *digest);
|
||||
void SHA1_Init(SHA1_CTX *);
|
||||
void SHA1_Update(SHA1_CTX *, const uint8_t * msg, int len);
|
||||
void SHA1_Final(uint8_t *digest, SHA1_CTX *);
|
||||
|
||||
/**************************************************************************
|
||||
* MD5 declarations
|
||||
* MD2 declarations
|
||||
**************************************************************************/
|
||||
|
||||
/* MD5 context. */
|
||||
#define MD2_SIZE 16
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char cksum[16]; /* checksum of the data block */
|
||||
unsigned char state[48]; /* intermediate digest state */
|
||||
unsigned char buffer[16]; /* data block being processed */
|
||||
int left; /* amount of data in buffer */
|
||||
} MD2_CTX;
|
||||
|
||||
EXP_FUNC void STDCALL MD2_Init(MD2_CTX *ctx);
|
||||
EXP_FUNC void STDCALL MD2_Update(MD2_CTX *ctx, const uint8_t *input, int ilen);
|
||||
EXP_FUNC void STDCALL MD2_Final(uint8_t *digest, MD2_CTX *ctx);
|
||||
|
||||
/**************************************************************************
|
||||
* MD5 declarations
|
||||
**************************************************************************/
|
||||
|
||||
#define MD5_SIZE 16
|
||||
|
||||
@ -110,9 +154,9 @@ typedef struct
|
||||
uint8_t buffer[64]; /* input buffer */
|
||||
} MD5_CTX;
|
||||
|
||||
void MD5Init(MD5_CTX *);
|
||||
void MD5Update(MD5_CTX *, const uint8_t *msg, int len);
|
||||
void MD5Final(MD5_CTX *, uint8_t *digest);
|
||||
EXP_FUNC void STDCALL MD5_Init(MD5_CTX *);
|
||||
EXP_FUNC void STDCALL MD5_Update(MD5_CTX *, const uint8_t *msg, int len);
|
||||
EXP_FUNC void STDCALL MD5_Final(uint8_t *digest, MD5_CTX *);
|
||||
|
||||
/**************************************************************************
|
||||
* HMAC declarations
|
||||
@ -122,26 +166,6 @@ void hmac_md5(const uint8_t *msg, int length, const uint8_t *key,
|
||||
void hmac_sha1(const uint8_t *msg, int length, const uint8_t *key,
|
||||
int key_len, uint8_t *digest);
|
||||
|
||||
/**************************************************************************
|
||||
* RNG declarations
|
||||
**************************************************************************/
|
||||
void RNG_initialize(const uint8_t *seed_buf, int size);
|
||||
void RNG_terminate(void);
|
||||
void get_random(int num_rand_bytes, uint8_t *rand_data);
|
||||
//void get_random_NZ(int num_rand_bytes, uint8_t *rand_data);
|
||||
|
||||
#include <ipxe/random_nz.h>
|
||||
static inline void get_random_NZ(int num_rand_bytes, uint8_t *rand_data) {
|
||||
/* AXTLS does not check for failures when generating random
|
||||
* data. Rely on the fact that get_random_nz() does not
|
||||
* request prediction resistance (and so cannot introduce new
|
||||
* failures) and therefore any potential failure must already
|
||||
* have been encountered by e.g. tls_generate_random(), which
|
||||
* does check for failures.
|
||||
*/
|
||||
get_random_nz ( rand_data, num_rand_bytes );
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* RSA declarations
|
||||
**************************************************************************/
|
||||
@ -159,7 +183,6 @@ typedef struct
|
||||
bigint *qInv; /* q^-1 mod p */
|
||||
#endif
|
||||
int num_octets;
|
||||
bigint *sig_m; /* signature modulus */
|
||||
BI_CTX *bi_ctx;
|
||||
} RSA_CTX;
|
||||
|
||||
@ -182,125 +205,22 @@ void RSA_free(RSA_CTX *ctx);
|
||||
int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data,
|
||||
int is_decryption);
|
||||
bigint *RSA_private(const RSA_CTX *c, bigint *bi_msg);
|
||||
#ifdef CONFIG_SSL_CERT_VERIFICATION
|
||||
bigint *RSA_raw_sign_verify(RSA_CTX *c, bigint *bi_msg);
|
||||
#if defined(CONFIG_SSL_CERT_VERIFICATION) || defined(CONFIG_SSL_GENERATE_X509_CERT)
|
||||
bigint *RSA_sign_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
|
||||
bigint *modulus, bigint *pub_exp);
|
||||
bigint *RSA_public(const RSA_CTX *c, bigint *bi_msg);
|
||||
bigint *RSA_public(const RSA_CTX * c, bigint *bi_msg);
|
||||
int RSA_encrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len,
|
||||
uint8_t *out_data, int is_signing);
|
||||
void RSA_print(const RSA_CTX *ctx);
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
* ASN1 declarations
|
||||
* RNG declarations
|
||||
**************************************************************************/
|
||||
#define X509_OK 0
|
||||
#define X509_NOT_OK -1
|
||||
#define X509_VFY_ERROR_NO_TRUSTED_CERT -2
|
||||
#define X509_VFY_ERROR_BAD_SIGNATURE -3
|
||||
#define X509_VFY_ERROR_NOT_YET_VALID -4
|
||||
#define X509_VFY_ERROR_EXPIRED -5
|
||||
#define X509_VFY_ERROR_SELF_SIGNED -6
|
||||
#define X509_VFY_ERROR_INVALID_CHAIN -7
|
||||
#define X509_VFY_ERROR_UNSUPPORTED_DIGEST -8
|
||||
#define X509_INVALID_PRIV_KEY -9
|
||||
|
||||
/*
|
||||
* The Distinguished Name
|
||||
*/
|
||||
#define X509_NUM_DN_TYPES 3
|
||||
#define X509_COMMON_NAME 0
|
||||
#define X509_ORGANIZATION 1
|
||||
#define X509_ORGANIZATIONAL_TYPE 2
|
||||
|
||||
#define ASN1_INTEGER 0x02
|
||||
#define ASN1_BIT_STRING 0x03
|
||||
#define ASN1_OCTET_STRING 0x04
|
||||
#define ASN1_NULL 0x05
|
||||
#define ASN1_OID 0x06
|
||||
#define ASN1_PRINTABLE_STR 0x13
|
||||
#define ASN1_TELETEX_STR 0x14
|
||||
#define ASN1_IA5_STR 0x16
|
||||
#define ASN1_UTC_TIME 0x17
|
||||
#define ASN1_SEQUENCE 0x30
|
||||
#define ASN1_SET 0x31
|
||||
#define ASN1_IMPLICIT_TAG 0x80
|
||||
#define ASN1_EXPLICIT_TAG 0xa0
|
||||
|
||||
#define SALT_SIZE 8
|
||||
|
||||
struct _x509_ctx
|
||||
{
|
||||
char *ca_cert_dn[X509_NUM_DN_TYPES];
|
||||
char *cert_dn[X509_NUM_DN_TYPES];
|
||||
#if defined(_WIN32_WCE)
|
||||
long not_before;
|
||||
long not_after;
|
||||
#else
|
||||
time_t not_before;
|
||||
time_t not_after;
|
||||
#endif
|
||||
uint8_t *signature;
|
||||
uint16_t sig_len;
|
||||
uint8_t sig_type;
|
||||
RSA_CTX *rsa_ctx;
|
||||
bigint *digest;
|
||||
struct _x509_ctx *next;
|
||||
};
|
||||
|
||||
typedef struct _x509_ctx X509_CTX;
|
||||
|
||||
#ifdef CONFIG_SSL_CERT_VERIFICATION
|
||||
typedef struct
|
||||
{
|
||||
X509_CTX *cert[CONFIG_X509_MAX_CA_CERTS];
|
||||
} CA_CERT_CTX;
|
||||
#endif
|
||||
|
||||
int asn1_get_private_key(const uint8_t *buf, int len, RSA_CTX **rsa_ctx);
|
||||
int asn1_next_obj(const uint8_t *buf, int *offset, int obj_type);
|
||||
int asn1_skip_obj(const uint8_t *buf, int *offset, int obj_type);
|
||||
int asn1_get_int(const uint8_t *buf, int *offset, uint8_t **object);
|
||||
int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx);
|
||||
void x509_free(X509_CTX *x509_ctx);
|
||||
#ifdef CONFIG_SSL_CERT_VERIFICATION
|
||||
int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert);
|
||||
const uint8_t *x509_get_signature(const uint8_t *asn1_signature, int *len);
|
||||
#endif
|
||||
#ifdef CONFIG_SSL_FULL_MODE
|
||||
void x509_print(CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert);
|
||||
void x509_display_error(int error);
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
* MISC declarations
|
||||
**************************************************************************/
|
||||
|
||||
extern const char * const unsupported_str;
|
||||
|
||||
typedef void (*crypt_func)(void *, const uint8_t *, uint8_t *, int);
|
||||
typedef void (*hmac_func)(const uint8_t *msg, int length, const uint8_t *key,
|
||||
int key_len, uint8_t *digest);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *pre_data; /* include the ssl record bytes */
|
||||
uint8_t *data; /* the regular ssl data */
|
||||
int max_len;
|
||||
int index;
|
||||
} BUF_MEM;
|
||||
|
||||
BUF_MEM buf_new(void);
|
||||
void buf_grow(BUF_MEM *bm, int len);
|
||||
void buf_free(BUF_MEM *bm);
|
||||
int get_file(const char *filename, uint8_t **buf);
|
||||
|
||||
#if defined(CONFIG_SSL_FULL_MODE) || defined(WIN32) || defined(CONFIG_DEBUG)
|
||||
void print_blob(const char *format, const uint8_t *data, int size, ...);
|
||||
#else
|
||||
#define print_blob(...)
|
||||
#endif
|
||||
EXP_FUNC void STDCALL RNG_initialize(const uint8_t *seed_buf, int size);
|
||||
EXP_FUNC void STDCALL RNG_terminate(void);
|
||||
EXP_FUNC void STDCALL get_random(int num_rand_bytes, uint8_t *rand_data);
|
||||
void get_random_NZ(int num_rand_bytes, uint8_t *rand_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,61 +1,54 @@
|
||||
#ifndef AXTLS_OS_PORT_H
|
||||
#define AXTLS_OS_PORT_H
|
||||
|
||||
/**
|
||||
* @file os_port.h
|
||||
*
|
||||
* Trick the axtls code into building within our build environment.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_OS_PORT_H
|
||||
#define HEADER_OS_PORT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <byteswap.h>
|
||||
|
||||
#define STDCALL
|
||||
#define EXP_FUNC
|
||||
#define TTY_FLUSH()
|
||||
/** All imported axTLS files are licensed using the three-clause BSD licence */
|
||||
FILE_LICENCE ( BSD3 );
|
||||
|
||||
/** We can't actually abort, since we are effectively a kernel... */
|
||||
#define abort() assert ( 0 )
|
||||
|
||||
/** crypto_misc.c has a bad #ifdef */
|
||||
static inline void close ( int fd __unused ) {
|
||||
/* Do nothing */
|
||||
/** rsa.c uses alloca() */
|
||||
#define alloca( size ) __builtin_alloca ( size )
|
||||
|
||||
#include <ipxe/random_nz.h>
|
||||
static inline void get_random_NZ ( int num_rand_bytes, uint8_t *rand_data ) {
|
||||
/* AXTLS does not check for failures when generating random
|
||||
* data. Rely on the fact that get_random_nz() does not
|
||||
* request prediction resistance (and so cannot introduce new
|
||||
* failures) and therefore any potential failure must already
|
||||
* have been encountered by e.g. tls_generate_random(), which
|
||||
* does check for failures.
|
||||
*/
|
||||
get_random_nz ( rand_data, num_rand_bytes );
|
||||
}
|
||||
|
||||
typedef void FILE;
|
||||
/* Expose AES_encrypt() and AES_decrypt() in aes.o */
|
||||
#define aes 1
|
||||
#if OBJECT
|
||||
|
||||
static inline FILE * fopen ( const char *filename __unused,
|
||||
const char *mode __unused ) {
|
||||
return NULL;
|
||||
/* AES_CTX is not defined at this point, so omit prototypes */
|
||||
|
||||
static void AES_encrypt();
|
||||
static void AES_decrypt();
|
||||
|
||||
void axtls_aes_encrypt ( void *ctx, uint32_t *data ) {
|
||||
AES_encrypt ( ctx, data );
|
||||
}
|
||||
|
||||
static inline int fseek ( FILE *stream __unused, long offset __unused,
|
||||
int whence __unused ) {
|
||||
return -1;
|
||||
void axtls_aes_decrypt ( void *ctx, uint32_t *data ) {
|
||||
AES_decrypt ( ctx, data );
|
||||
}
|
||||
|
||||
static inline long ftell ( FILE *stream __unused ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline size_t fread ( void *ptr __unused, size_t size __unused,
|
||||
size_t nmemb __unused, FILE *stream __unused ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int fclose ( FILE *stream __unused ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define CONFIG_SSL_CERT_VERIFICATION 1
|
||||
#define CONFIG_SSL_MAX_CERTS 1
|
||||
#define CONFIG_X509_MAX_CA_CERTS 1
|
||||
#define CONFIG_SSL_EXPIRY_TIME 24
|
||||
#define CONFIG_SSL_ENABLE_CLIENT 1
|
||||
#define CONFIG_BIGINT_CLASSICAL 1
|
||||
#endif
|
||||
#undef aes
|
||||
|
||||
#endif
|
||||
|
@ -1,19 +1,31 @@
|
||||
/*
|
||||
* Copyright(C) 2006 Cameron Rich
|
||||
* Copyright (c) 2007, Cameron Rich
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of the axTLS project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -25,12 +37,9 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include "os_port.h"
|
||||
#include "crypto.h"
|
||||
|
||||
#ifdef CONFIG_BIGINT_CRT
|
||||
static bigint *bi_crt(const RSA_CTX *rsa, bigint *bi);
|
||||
#endif
|
||||
|
||||
void RSA_priv_key_new(RSA_CTX **ctx,
|
||||
const uint8_t *modulus, int mod_len,
|
||||
const uint8_t *pub_exp, int pub_len,
|
||||
@ -71,11 +80,16 @@ void RSA_pub_key_new(RSA_CTX **ctx,
|
||||
const uint8_t *pub_exp, int pub_len)
|
||||
{
|
||||
RSA_CTX *rsa_ctx;
|
||||
BI_CTX *bi_ctx = bi_initialize();
|
||||
BI_CTX *bi_ctx;
|
||||
|
||||
if (*ctx) /* if we load multiple certs, dump the old one */
|
||||
RSA_free(*ctx);
|
||||
|
||||
bi_ctx = bi_initialize();
|
||||
*ctx = (RSA_CTX *)calloc(1, sizeof(RSA_CTX));
|
||||
rsa_ctx = *ctx;
|
||||
rsa_ctx->bi_ctx = bi_ctx;
|
||||
rsa_ctx->num_octets = (mod_len & 0xFFF0);
|
||||
rsa_ctx->num_octets = mod_len;
|
||||
rsa_ctx->m = bi_import(bi_ctx, modulus, mod_len);
|
||||
bi_set_mod(bi_ctx, rsa_ctx->m, BIGINT_M_OFFSET);
|
||||
rsa_ctx->e = bi_import(bi_ctx, pub_exp, pub_len);
|
||||
@ -129,10 +143,10 @@ void RSA_free(RSA_CTX *rsa_ctx)
|
||||
int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data,
|
||||
uint8_t *out_data, int is_decryption)
|
||||
{
|
||||
int byte_size = ctx->num_octets;
|
||||
uint8_t *block;
|
||||
const int byte_size = ctx->num_octets;
|
||||
int i, size;
|
||||
bigint *decrypted_bi, *dat_bi;
|
||||
uint8_t *block = (uint8_t *)alloca(byte_size);
|
||||
|
||||
memset(out_data, 0, byte_size); /* initialise */
|
||||
|
||||
@ -146,7 +160,6 @@ int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data,
|
||||
#endif
|
||||
|
||||
/* convert to a normal block */
|
||||
block = (uint8_t *)malloc(byte_size);
|
||||
bi_export(ctx->bi_ctx, decrypted_bi, block, byte_size);
|
||||
|
||||
i = 10; /* start at the first possible non-padded byte */
|
||||
@ -170,7 +183,6 @@ int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data,
|
||||
if (size > 0)
|
||||
memcpy(out_data, &block[i], size);
|
||||
|
||||
free(block);
|
||||
return size ? size : -1;
|
||||
}
|
||||
|
||||
@ -180,7 +192,7 @@ int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data,
|
||||
bigint *RSA_private(const RSA_CTX *c, bigint *bi_msg)
|
||||
{
|
||||
#ifdef CONFIG_BIGINT_CRT
|
||||
return bi_crt(c, bi_msg);
|
||||
return bi_crt(c->bi_ctx, bi_msg, c->dP, c->dQ, c->p, c->q, c->qInv);
|
||||
#else
|
||||
BI_CTX *ctx = c->bi_ctx;
|
||||
ctx->mod_offset = BIGINT_M_OFFSET;
|
||||
@ -188,39 +200,6 @@ bigint *RSA_private(const RSA_CTX *c, bigint *bi_msg)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BIGINT_CRT
|
||||
/**
|
||||
* Use the Chinese Remainder Theorem to quickly perform RSA decrypts.
|
||||
* This should really be in bigint.c (and was at one stage), but needs
|
||||
* access to the RSA_CTX context...
|
||||
*/
|
||||
static bigint *bi_crt(const RSA_CTX *rsa, bigint *bi)
|
||||
{
|
||||
BI_CTX *ctx = rsa->bi_ctx;
|
||||
bigint *m1, *m2, *h;
|
||||
|
||||
/* Montgomery has a condition the 0 < x, y < m and these products violate
|
||||
* that condition. So disable Montgomery when using CRT */
|
||||
#if defined(CONFIG_BIGINT_MONTGOMERY)
|
||||
ctx->use_classical = 1;
|
||||
#endif
|
||||
ctx->mod_offset = BIGINT_P_OFFSET;
|
||||
m1 = bi_mod_power(ctx, bi_copy(bi), rsa->dP);
|
||||
|
||||
ctx->mod_offset = BIGINT_Q_OFFSET;
|
||||
m2 = bi_mod_power(ctx, bi, rsa->dQ);
|
||||
|
||||
h = bi_subtract(ctx, bi_add(ctx, m1, rsa->p), bi_copy(m2), NULL);
|
||||
h = bi_multiply(ctx, h, rsa->qInv);
|
||||
ctx->mod_offset = BIGINT_P_OFFSET;
|
||||
h = bi_residue(ctx, h);
|
||||
#if defined(CONFIG_BIGINT_MONTGOMERY)
|
||||
ctx->use_classical = 0; /* reset for any further operation */
|
||||
#endif
|
||||
return bi_add(ctx, m2, bi_multiply(ctx, rsa->q, h));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SSL_FULL_MODE
|
||||
/**
|
||||
* Used for diagnostics.
|
||||
@ -238,7 +217,7 @@ void RSA_print(const RSA_CTX *rsa_ctx)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SSL_CERT_VERIFICATION
|
||||
#if defined(CONFIG_SSL_CERT_VERIFICATION) || defined(CONFIG_SSL_GENERATE_X509_CERT)
|
||||
/**
|
||||
* Performs c = m^e mod n
|
||||
*/
|
||||
@ -279,54 +258,12 @@ int RSA_encrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len,
|
||||
/* now encrypt it */
|
||||
dat_bi = bi_import(ctx->bi_ctx, out_data, byte_size);
|
||||
encrypt_bi = is_signing ? RSA_private(ctx, dat_bi) :
|
||||
RSA_public(ctx, dat_bi);
|
||||
RSA_public(ctx, dat_bi);
|
||||
bi_export(ctx->bi_ctx, encrypt_bi, out_data, byte_size);
|
||||
|
||||
/* save a few bytes of memory */
|
||||
bi_clear_cache(ctx->bi_ctx);
|
||||
return byte_size;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Take a signature and decrypt it.
|
||||
*/
|
||||
bigint *RSA_sign_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
|
||||
bigint *modulus, bigint *pub_exp)
|
||||
{
|
||||
uint8_t *block;
|
||||
int i, size;
|
||||
bigint *decrypted_bi, *dat_bi;
|
||||
bigint *bir = NULL;
|
||||
|
||||
block = (uint8_t *)malloc(sig_len);
|
||||
|
||||
/* decrypt */
|
||||
dat_bi = bi_import(ctx, sig, sig_len);
|
||||
ctx->mod_offset = BIGINT_M_OFFSET;
|
||||
|
||||
/* convert to a normal block */
|
||||
decrypted_bi = bi_mod_power2(ctx, dat_bi, modulus, pub_exp);
|
||||
|
||||
bi_export(ctx, decrypted_bi, block, sig_len);
|
||||
ctx->mod_offset = BIGINT_M_OFFSET;
|
||||
|
||||
i = 10; /* start at the first possible non-padded byte */
|
||||
while (block[i++] && i < sig_len);
|
||||
size = sig_len - i;
|
||||
|
||||
/* get only the bit we want */
|
||||
if (size > 0)
|
||||
{
|
||||
int len;
|
||||
const uint8_t *sig_ptr = x509_get_signature(&block[i], &len);
|
||||
|
||||
if (sig_ptr)
|
||||
{
|
||||
bir = bi_import(ctx, sig_ptr, len);
|
||||
}
|
||||
}
|
||||
|
||||
free(block);
|
||||
return bir;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_SSL_CERT_VERIFICATION */
|
||||
|
@ -20,6 +20,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/crypto.h>
|
||||
#include <ipxe/cbc.h>
|
||||
@ -119,7 +120,7 @@ static void aes_encrypt ( void *ctx, const void *src, void *dst,
|
||||
assert ( len == AES_BLOCKSIZE );
|
||||
if ( aes_ctx->decrypting )
|
||||
assert ( 0 );
|
||||
aes_call_axtls ( &aes_ctx->axtls_ctx, src, dst, AES_encrypt );
|
||||
aes_call_axtls ( &aes_ctx->axtls_ctx, src, dst, axtls_aes_encrypt );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,7 +140,7 @@ static void aes_decrypt ( void *ctx, const void *src, void *dst,
|
||||
AES_convert_key ( &aes_ctx->axtls_ctx );
|
||||
aes_ctx->decrypting = 1;
|
||||
}
|
||||
aes_call_axtls ( &aes_ctx->axtls_ctx, src, dst, AES_decrypt );
|
||||
aes_call_axtls ( &aes_ctx->axtls_ctx, src, dst, axtls_aes_decrypt );
|
||||
}
|
||||
|
||||
/** Basic AES algorithm */
|
||||
|
@ -155,6 +155,11 @@ int x509_rsa_public_key ( const struct asn1_cursor *certificate,
|
||||
DBG_HDA ( 0, certificate->data, certificate->len );
|
||||
return -ENOTSUP;
|
||||
}
|
||||
if ( modulus.len && ( ! *( ( uint8_t * ) modulus.data ) ) ) {
|
||||
/* Skip positive sign byte */
|
||||
modulus.data++;
|
||||
modulus.len--;
|
||||
}
|
||||
memcpy ( &exponent, &pubkey, sizeof ( exponent ) );
|
||||
rc = ( asn1_skip ( &exponent, ASN1_INTEGER ), /* modulus */
|
||||
asn1_enter ( &exponent, ASN1_INTEGER ) /* publicExponent */ );
|
||||
@ -163,6 +168,11 @@ int x509_rsa_public_key ( const struct asn1_cursor *certificate,
|
||||
DBG_HDA ( 0, certificate->data, certificate->len );
|
||||
return -ENOTSUP;
|
||||
}
|
||||
if ( exponent.len && ( ! *( ( uint8_t * ) exponent.data ) ) ) {
|
||||
/* Skip positive sign byte */
|
||||
exponent.data++;
|
||||
exponent.len--;
|
||||
}
|
||||
|
||||
/* Allocate space and copy out modulus and exponent */
|
||||
rsa_pubkey->modulus = malloc ( modulus.len + exponent.len );
|
||||
|
@ -21,6 +21,10 @@ struct aes_context {
|
||||
/** AES context size */
|
||||
#define AES_CTX_SIZE sizeof ( struct aes_context )
|
||||
|
||||
/* AXTLS functions */
|
||||
extern void axtls_aes_encrypt ( const AES_CTX *ctx, uint32_t *data );
|
||||
extern void axtls_aes_decrypt ( const AES_CTX *ctx, uint32_t *data );
|
||||
|
||||
extern struct cipher_algorithm aes_algorithm;
|
||||
extern struct cipher_algorithm aes_cbc_algorithm;
|
||||
|
||||
|
@ -794,7 +794,7 @@ static int tls_send_certificate ( struct tls_session *tls ) {
|
||||
*/
|
||||
static int tls_send_client_key_exchange ( struct tls_session *tls ) {
|
||||
/* FIXME: Hack alert */
|
||||
RSA_CTX *rsa_ctx;
|
||||
RSA_CTX *rsa_ctx = NULL;
|
||||
RSA_pub_key_new ( &rsa_ctx, tls->rsa.modulus, tls->rsa.modulus_len,
|
||||
tls->rsa.exponent, tls->rsa.exponent_len );
|
||||
struct {
|
||||
|
Loading…
x
Reference in New Issue
Block a user