david/ipxe
Archived
1
0

[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:
Michael Brown 2012-03-09 15:45:56 +00:00
parent 74b1e706a8
commit 1c29b4d979
12 changed files with 508 additions and 602 deletions

View File

@ -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 * All rights reserved.
* 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.
* *
* This library is distributed in the hope that it will be useful, * Redistribution and use in source and binary forms, with or without
* but WITHOUT ANY WARRANTY; without even the implied warranty of * modification, are permitted provided that the following conditions are met:
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * * Redistributions of source code must retain the above copyright notice,
* along with this library; if not, write to the Free Software * this list of conditions and the following disclaimer.
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * 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 * 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 * 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 <string.h>
#include "os_port.h"
#include "crypto.h" #include "crypto.h"
/* all commented out in skeleton mode */ /* all commented out in skeleton mode */
@ -64,10 +75,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
(f8)^=rot2(f4), \ (f8)^=rot2(f4), \
(f8)^rot1(f9)) (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 * AES S-box
*/ */
@ -154,11 +161,15 @@ static const unsigned char Rcon[30]=
0xb3,0x7d,0xfa,0xef,0xc5,0x91, 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 /* Perform doubling in Galois Field GF(2^8) using the irreducible polynomial
x^8+x^4+x^3+x+1 */ x^8+x^4+x^3+x+1 */
static unsigned char AES_xtime(uint32_t x) 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 = ctx->ks;
k += 4; k += 4;
for (i=ctx->rounds*4; i>4; i--) for (i= ctx->rounds*4; i > 4; i--)
{ {
w= *k; w= *k;
w = inv_mix_col(w,t1,t2,t3,t4); 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. * 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) void AES_cbc_encrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
{ {
uint32_t tin0, tin1, tin2, tin3; int i;
uint32_t tout0, tout1, tout2, tout3; uint32_t tin[4], tout[4], iv[4];
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;
n2l(iv, tout0); memcpy(iv, ctx->iv, AES_IV_SIZE);
n2l(iv, tout1); for (i = 0; i < 4; i++)
n2l(iv, tout2); tout[i] = ntohl(iv[i]);
n2l(iv, tout3);
iv -= 4;
for (length -= 16; length >= 0; length -= 16) for (length -= AES_BLOCKSIZE; length >= 0; length -= AES_BLOCKSIZE)
{ {
n2l(msg_32, tin0); uint32_t msg_32[4];
n2l(msg_32, tin1); uint32_t out_32[4];
n2l(msg_32, tin2); memcpy(msg_32, msg, AES_BLOCKSIZE);
n2l(msg_32, tin3); msg += AES_BLOCKSIZE;
tin[0] = tin0^tout0;
tin[1] = tin1^tout1; for (i = 0; i < 4; i++)
tin[2] = tin2^tout2; tin[i] = ntohl(msg_32[i])^tout[i];
tin[3] = tin3^tout3;
AES_encrypt(ctx, tin); AES_encrypt(ctx, tin);
tout0 = tin[0]; for (i = 0; i < 4; i++)
l2n(tout0, out_32); {
tout1 = tin[1]; tout[i] = tin[i];
l2n(tout1, out_32); out_32[i] = htonl(tout[i]);
tout2 = tin[2];
l2n(tout2, out_32);
tout3 = tin[3];
l2n(tout3, out_32);
} }
l2n(tout0, iv); memcpy(out, out_32, AES_BLOCKSIZE);
l2n(tout1, iv); out += AES_BLOCKSIZE;
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) void AES_cbc_decrypt(AES_CTX *ctx, const uint8_t *msg, uint8_t *out, int length)
{ {
uint32_t tin0, tin1, tin2, tin3; int i;
uint32_t xor0,xor1,xor2,xor3; uint32_t tin[4], xor[4], tout[4], data[4], iv[4];
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;
n2l(iv ,xor0); memcpy(iv, ctx->iv, AES_IV_SIZE);
n2l(iv, xor1); for (i = 0; i < 4; i++)
n2l(iv, xor2); xor[i] = ntohl(iv[i]);
n2l(iv, xor3);
iv -= 4;
for (length-=16; length >= 0; length -= 16) for (length -= 16; length >= 0; length -= 16)
{ {
n2l(msg_32, tin0); uint32_t msg_32[4];
n2l(msg_32, tin1); uint32_t out_32[4];
n2l(msg_32, tin2); memcpy(msg_32, msg, AES_BLOCKSIZE);
n2l(msg_32, tin3); msg += AES_BLOCKSIZE;
data[0] = tin0; for (i = 0; i < 4; i++)
data[1] = tin1; {
data[2] = tin2; tin[i] = ntohl(msg_32[i]);
data[3] = tin3; data[i] = tin[i];
}
AES_decrypt(ctx, data); AES_decrypt(ctx, data);
tout0 = data[0]^xor0; for (i = 0; i < 4; i++)
tout1 = data[1]^xor1; {
tout2 = data[2]^xor2; tout[i] = data[i]^xor[i];
tout3 = data[3]^xor3; 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);
} }
l2n(xor0, iv); memcpy(out, out_32, AES_BLOCKSIZE);
l2n(xor1, iv); out += AES_BLOCKSIZE;
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 * 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. /* To make this code smaller, generate the sbox entries on the fly.
* This will have a really heavy effect upon performance. * 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 */ /* Pre-round key addition */
for (row = 0; row < 4; row++) for (row = 0; row < 4; row++)
{
data[row] ^= *(k++); data[row] ^= *(k++);
}
/* Encrypt one block. */ /* Encrypt one block. */
for (curr_rnd = 0; curr_rnd < rounds; curr_rnd++) 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; tmp1 = a0 ^ a1 ^ a2 ^ a3;
old_a0 = a0; old_a0 = a0;
a0 ^= tmp1 ^ AES_xtime(a0 ^ a1); a0 ^= tmp1 ^ AES_xtime(a0 ^ a1);
a1 ^= tmp1 ^ AES_xtime(a1 ^ a2); a1 ^= tmp1 ^ AES_xtime(a1 ^ a2);
a2 ^= tmp1 ^ AES_xtime(a2 ^ a3); a2 ^= tmp1 ^ AES_xtime(a2 ^ a3);
a3 ^= tmp1 ^ AES_xtime(a3 ^ old_a0); a3 ^= tmp1 ^ AES_xtime(a3 ^ old_a0);
} }
tmp[row] = ((a0 << 24) | (a1 << 16) | (a2 << 8) | a3); 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 /* KeyAddition - note that it is vital that this loop is separate from
the MixColumn operation, which must be atomic...*/ the MixColumn operation, which must be atomic...*/
for (row = 0; row < 4; row++) for (row = 0; row < 4; row++)
{
data[row] = tmp[row] ^ *(k++); data[row] = tmp[row] ^ *(k++);
} }
}
} }
/** /**
* Decrypt a single block (16 bytes) of data * 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 tmp[4];
uint32_t xt0,xt1,xt2,xt3,xt4,xt5,xt6; uint32_t xt0,xt1,xt2,xt3,xt4,xt5,xt6;
uint32_t a0, a1, a2, a3, row; uint32_t a0, a1, a2, a3, row;
int curr_rnd; int curr_rnd;
int rounds = ctx->rounds; 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 */ /* pre-round key addition */
for (row=4; row > 0;row--) for (row=4; row > 0;row--)
{
data[row-1] ^= *(--k); data[row-1] ^= *(--k);
}
/* Decrypt one block */ /* 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 */ /* Perform ByteSub and ShiftRow operations together */
for (row = 4; row > 0; row--) for (row = 4; row > 0; row--)
@ -469,10 +450,8 @@ void AES_decrypt(const AES_CTX *ctx, uint32_t *data)
} }
for (row = 4; row > 0; row--) for (row = 4; row > 0; row--)
{
data[row-1] = tmp[row-1] ^ *(--k); data[row-1] = tmp[row-1] ^ *(--k);
} }
}
} }
#endif #endif

View File

@ -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 * All rights reserved.
* 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.
* *
* This library is distributed in the hope that it will be useful, * Redistribution and use in source and binary forms, with or without
* but WITHOUT ANY WARRANTY; without even the implied warranty of * modification, are permitted provided that the following conditions are met:
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * * Redistributions of source code must retain the above copyright notice,
* along with this library; if not, write to the Free Software * this list of conditions and the following disclaimer.
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * 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 <string.h>
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
#include "os_port.h"
#include "bigint.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_multiply(BI_CTX *ctx, bigint *bi, comp i);
static bigint *bi_int_divide(BI_CTX *ctx, bigint *biR, comp denom); 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 bigint *trim(bigint *bi);
static void more_comps(bigint *bi, int n); static void more_comps(bigint *bi, int n);
#if defined(CONFIG_BIGINT_KARATSUBA) || defined(CONFIG_BIGINT_BARRETT) || \ #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 #ifdef CONFIG_BIGINT_CHECK_ON
static void check(const bigint *bi); static void check(const bigint *bi);
#else
#define check(A) /**< disappears in normal production mode */
#endif #endif
/** /**
* @brief Start a new bigint context. * @brief Start a new bigint context.
* @return A bigint context. * @return A bigint context.
@ -97,8 +117,6 @@ BI_CTX *bi_initialize(void)
*/ */
void bi_terminate(BI_CTX *ctx) void bi_terminate(BI_CTX *ctx)
{ {
bigint *p, *pn;
bi_depermanent(ctx->bi_radix); bi_depermanent(ctx->bi_radix);
bi_free(ctx, ctx->bi_radix); bi_free(ctx, ctx->bi_radix);
@ -111,6 +129,20 @@ void bi_terminate(BI_CTX *ctx)
abort(); 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) for (p = ctx->free_list; p != NULL; p = pn)
{ {
pn = p->next; pn = p->next;
@ -118,7 +150,8 @@ void bi_terminate(BI_CTX *ctx)
free(p); free(p);
} }
free(ctx); ctx->free_count = 0;
ctx->free_list = NULL;
} }
/** /**
@ -410,7 +443,6 @@ bigint *bi_divide(BI_CTX *ctx, bigint *u, bigint *v, int is_mod)
else else
{ {
q_dash = (comp)(((long_comp)U(0)*COMP_RADIX + U(1))/V1); q_dash = (comp)(((long_comp)U(0)*COMP_RADIX + U(1))/V1);
}
if (v->size > 1 && V2) if (v->size > 1 && V2)
{ {
@ -424,6 +456,7 @@ bigint *bi_divide(BI_CTX *ctx, bigint *u, bigint *v, int is_mod)
q_dash--; q_dash--;
} }
} }
}
/* multiply and subtract */ /* multiply and subtract */
if (q_dash) if (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. * 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) static bigint *bi_int_divide(BI_CTX *ctx __unused, bigint *biR, comp denom)
{ {
int i = biR->size - 1; 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]; r = (r<<COMP_BIT_SIZE) + biR->comps[i];
biR->comps[i] = (comp)(r / denom); biR->comps[i] = (comp)(r / denom);
r %= denom; r %= denom;
} while (--i != 0); } while (--i >= 0);
return trim(biR); return trim(biR);
} }
@ -690,10 +724,11 @@ void bi_export(BI_CTX *ctx, bigint *x, uint8_t *data, int size)
if (k < 0) if (k < 0)
{ {
break; goto buf_done;
} }
} }
} }
buf_done:
bi_free(ctx, x); bi_free(ctx, x);
} }
@ -769,10 +804,15 @@ void bi_free_mod(BI_CTX *ctx, int mod_offset)
/** /**
* Perform a standard multiplication between two bigints. * 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 i = 0, j;
int n = bia->size; int n = bia->size;
int t = bib->size; int t = bib->size;
bigint *biR = alloc(ctx, n + t); bigint *biR = alloc(ctx, n + t);
@ -785,23 +825,33 @@ static bigint *regular_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
/* clear things to start with */ /* clear things to start with */
memset(biR->comps, 0, ((n+t)*COMP_BYTE_SIZE)); memset(biR->comps, 0, ((n+t)*COMP_BYTE_SIZE));
i = 0;
do do
{ {
long_comp tmp;
comp carry = 0; comp carry = 0;
comp b = *sb++; int r_index = i;
i_plus_j = i;
j = 0; j = 0;
if (outer_partial && outer_partial-i > 0 && outer_partial < n)
{
r_index = outer_partial-1;
j = outer_partial-i-1;
}
do do
{ {
long_comp tmp = sr[i_plus_j] + (long_comp)sa[j]*b + carry; if (inner_partial && r_index >= inner_partial)
sr[i_plus_j++] = (comp)tmp; /* downsize */ {
carry = (comp)(tmp >> COMP_BIT_SIZE); 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); } while (++j < n);
sr[i_plus_j] = carry; sr[r_index] = carry;
} while (++i < t); } while (++i < t);
bi_free(ctx, bia); bi_free(ctx, bia);
@ -881,12 +931,12 @@ bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib)
#ifdef CONFIG_BIGINT_KARATSUBA #ifdef CONFIG_BIGINT_KARATSUBA
if (min(bia->size, bib->size) < MUL_KARATSUBA_THRESH) 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); return karatsuba(ctx, bia, bib, 0);
#else #else
return regular_multiply(ctx, bia, bib); return regular_multiply(ctx, bia, bib, 0, 0);
#endif #endif
} }
@ -898,47 +948,46 @@ static bigint *regular_square(BI_CTX *ctx, bigint *bi)
{ {
int t = bi->size; int t = bi->size;
int i = 0, j; int i = 0, j;
bigint *biR = alloc(ctx, t*2); bigint *biR = alloc(ctx, t*2+1);
comp *w = biR->comps; comp *w = biR->comps;
comp *x = bi->comps; comp *x = bi->comps;
comp carry; long_comp carry;
memset(w, 0, biR->size*COMP_BYTE_SIZE); memset(w, 0, biR->size*COMP_BYTE_SIZE);
do do
{ {
long_comp tmp = w[2*i] + (long_comp)x[i]*x[i]; long_comp tmp = w[2*i] + (long_comp)x[i]*x[i];
comp u = 0;
w[2*i] = (comp)tmp; w[2*i] = (comp)tmp;
carry = (comp)(tmp >> COMP_BIT_SIZE); carry = tmp >> COMP_BIT_SIZE;
for (j = i+1; j < t; j++) for (j = i+1; j < t; j++)
{ {
uint8_t c = 0;
long_comp xx = (long_comp)x[i]*x[j]; 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 */ tmp = (xx<<1);
{
blob += COMP_RADIX;
}
u = 0; if ((COMP_MAX-tmp) < w[i+j])
if (xx & COMP_BIG_MSB) /* check for overflow */ c = 1;
{
u = 1;
}
tmp = 2*xx + blob; tmp += w[i+j];
if ((COMP_MAX-tmp) < carry)
c = 1;
tmp += carry;
w[i+j] = (comp)tmp; 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; tmp = w[i+t] + carry;
w[i+t] = (comp)tmp;
if (u) w[i+t+1] = tmp >> COMP_BIT_SIZE;
{
w[i+t+1] = 1; /* add carry */
}
} while (++i < t); } while (++i < t);
bi_free(ctx, bi); bi_free(ctx, bi);
@ -1092,7 +1141,7 @@ static int find_max_exp_index(bigint *biexp)
} }
shift >>= 1; shift >>= 1;
} while (--i != 0); } while (i-- != 0);
return -1; /* error - must have been a leading 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; shift <<= 1;
} }
return test & shift; return (test & shift) != 0;
} }
#ifdef CONFIG_BIGINT_CHECK_ON #ifdef CONFIG_BIGINT_CHECK_ON
@ -1210,81 +1259,6 @@ static bigint *comp_mod(bigint *bi, int mod)
return bi; 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. * @brief Perform a single Barrett reduction.
* @param ctx [in] The bigint session context. * @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); q1 = comp_right_shift(bi_clone(ctx, bi), k-1);
/* do outer partial multiply */ /* 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); q3 = comp_right_shift(q2, k+1);
r1 = comp_mod(bi, k+1); r1 = comp_mod(bi, k+1);
/* do inner partial multiply */ /* 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); r = bi_subtract(ctx, r1, r2, NULL);
/* if (r >= m) r = r - m; */ /* 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 ctx [in] The bigint session context.
* @param bi [in] The bigint on which to perform the mod power operation. * @param bi [in] The bigint on which to perform the mod power operation.
* @param biexp [in] The bigint exponent. * @param biexp [in] The bigint exponent.
* @return The result of the mod exponentiation operation
* @see bi_set_mod(). * @see bi_set_mod().
*/ */
bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp) 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 bi [in] The bigint to perform the exp/mod.
* @param bim [in] The temporary modulus. * @param bim [in] The temporary modulus.
* @param biexp [in] The bigint exponent. * @param biexp [in] The bigint exponent.
* @return The result of the mod exponentiation operation
* @see bi_set_mod(). * @see bi_set_mod().
*/ */
bigint *bi_mod_power2(BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp) 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; return biR;
} }
#endif #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
/** @} */ /** @} */

View File

@ -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 * All rights reserved.
* 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.
* *
* This library is distributed in the hope that it will be useful, * Redistribution and use in source and binary forms, with or without
* but WITHOUT ANY WARRANTY; without even the implied warranty of * modification, are permitted provided that the following conditions are met:
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * * Redistributions of source code must retain the above copyright notice,
* along with this library; if not, write to the Free Software * this list of conditions and the following disclaimer.
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * 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 #ifndef BIGINT_HEADER
#define BIGINT_HEADER #define BIGINT_HEADER
/* enable features based on a 'super-set' capbaility. */ #include "crypto.h"
#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 "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); BI_CTX *bi_initialize(void);
void bi_terminate(BI_CTX *ctx); void bi_terminate(BI_CTX *ctx);
void bi_permanent(bigint *bi); void bi_permanent(bigint *bi);
void bi_depermanent(bigint *bi); void bi_depermanent(bigint *bi);
void bi_clear_cache(BI_CTX *ctx);
void bi_free(BI_CTX *ctx, bigint *bi); void bi_free(BI_CTX *ctx, bigint *bi);
bigint *bi_copy(bigint *bi); bigint *bi_copy(bigint *bi);
bigint *bi_clone(BI_CTX *ctx, const 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) #define bi_square(A, B) bi_multiply(A, bi_copy(B), B)
#endif #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 #endif

View File

@ -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 * All rights reserved.
* 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.
* *
* This library is distributed in the hope that it will be useful, * Redistribution and use in source and binary forms, with or without
* but WITHOUT ANY WARRANTY; without even the implied warranty of * modification, are permitted provided that the following conditions are met:
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * * Redistributions of source code must retain the above copyright notice,
* along with this library; if not, write to the Free Software * this list of conditions and the following disclaimer.
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * 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 #ifndef BIGINT_IMPL_HEADER
@ -30,20 +42,39 @@
#endif #endif
/* Architecture specific functions for big ints */ /* 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 #ifdef WIN32
#define COMP_RADIX 4294967296i64 #define COMP_RADIX 4294967296i64
#define COMP_BIG_MSB 0x8000000000000000i64 #define COMP_MAX 0xFFFFFFFFFFFFFFFFui64
#else #else
#define COMP_RADIX 4294967296ULL /**< Max component + 1 */ #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 #endif
#define COMP_BIT_SIZE 32 /**< Number of bits in a component. */ #define COMP_BIT_SIZE 32 /**< Number of bits in a component. */
#define COMP_BYTE_SIZE 4 /**< Number of bytes in a component. */ #define COMP_BYTE_SIZE 4 /**< Number of bytes in a component. */
#define COMP_NUM_NIBBLES 8 /**< Used For diagnostics only. */ #define COMP_NUM_NIBBLES 8 /**< Used For diagnostics only. */
typedef uint32_t comp; /**< A single precision component. */ typedef uint32_t comp; /**< A single precision component. */
typedef uint64_t long_comp; /**< A double precision component. */ typedef uint64_t long_comp; /**< A double precision component. */
typedef int64_t slong_comp; /**< A signed double precision component. */ typedef int64_t slong_comp; /**< A signed double precision component. */
#endif
/** /**
* @struct _bigint * @struct _bigint
@ -97,9 +128,4 @@ typedef struct /**< A big integer "session" context. */
#define PERMANENT 0x7FFF55AA /**< A magic number for permanents. */ #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 #endif

13
src/crypto/axtls/config.h Normal file
View 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

View File

@ -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 * All rights reserved.
* 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.
* *
* This library is distributed in the hope that it will be useful, * Redistribution and use in source and binary forms, with or without
* but WITHOUT ANY WARRANTY; without even the implied warranty of * modification, are permitted provided that the following conditions are met:
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * * Redistributions of source code must retain the above copyright notice,
* along with this library; if not, write to the Free Software * this list of conditions and the following disclaimer.
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * 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 * @file crypto.h
*/ */
@ -29,20 +39,40 @@ FILE_LICENCE ( GPL2_OR_LATER );
extern "C" { extern "C" {
#endif #endif
#include "config.h"
#include "bigint_impl.h"
#include "bigint.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 * AES declarations
**************************************************************************/ **************************************************************************/
#define AES_MAXROUNDS 14 #define AES_MAXROUNDS 14
#define AES_BLOCKSIZE 16
#define AES_IV_SIZE 16
typedef struct aes_key_st typedef struct aes_key_st
{ {
uint16_t rounds; uint16_t rounds;
uint16_t key_size; uint16_t key_size;
uint32_t ks[(AES_MAXROUNDS+1)*8]; uint32_t ks[(AES_MAXROUNDS+1)*8];
uint8_t iv[16]; uint8_t iv[AES_IV_SIZE];
} AES_CTX; } AES_CTX;
typedef enum typedef enum
@ -57,8 +87,6 @@ void AES_cbc_encrypt(AES_CTX *ctx, const uint8_t *msg,
uint8_t *out, int length); uint8_t *out, int length);
void AES_cbc_decrypt(AES_CTX *ks, const uint8_t *in, 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_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 * RC4 declarations
@ -66,7 +94,7 @@ void AES_decrypt(const AES_CTX *ctx, uint32_t *data);
typedef struct typedef struct
{ {
int x, y, m[256]; uint8_t x, y, m[256];
} RC4_CTX; } RC4_CTX;
void RC4_setup(RC4_CTX *s, const uint8_t *key, int length); void RC4_setup(RC4_CTX *s, const uint8_t *key, int length);
@ -91,16 +119,32 @@ typedef struct
uint8_t Message_Block[64]; /* 512-bit message blocks */ uint8_t Message_Block[64]; /* 512-bit message blocks */
} SHA1_CTX; } SHA1_CTX;
void SHA1Init(SHA1_CTX *); void SHA1_Init(SHA1_CTX *);
void SHA1Update(SHA1_CTX *, const uint8_t * msg, int len); void SHA1_Update(SHA1_CTX *, const uint8_t * msg, int len);
void SHA1Final(SHA1_CTX *, uint8_t *digest); void SHA1_Final(uint8_t *digest, SHA1_CTX *);
/**************************************************************************
* MD2 declarations
**************************************************************************/
#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 * MD5 declarations
**************************************************************************/ **************************************************************************/
/* MD5 context. */
#define MD5_SIZE 16 #define MD5_SIZE 16
typedef struct typedef struct
@ -110,9 +154,9 @@ typedef struct
uint8_t buffer[64]; /* input buffer */ uint8_t buffer[64]; /* input buffer */
} MD5_CTX; } MD5_CTX;
void MD5Init(MD5_CTX *); EXP_FUNC void STDCALL MD5_Init(MD5_CTX *);
void MD5Update(MD5_CTX *, const uint8_t *msg, int len); EXP_FUNC void STDCALL MD5_Update(MD5_CTX *, const uint8_t *msg, int len);
void MD5Final(MD5_CTX *, uint8_t *digest); EXP_FUNC void STDCALL MD5_Final(uint8_t *digest, MD5_CTX *);
/************************************************************************** /**************************************************************************
* HMAC declarations * 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, void hmac_sha1(const uint8_t *msg, int length, const uint8_t *key,
int key_len, uint8_t *digest); 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 * RSA declarations
**************************************************************************/ **************************************************************************/
@ -159,7 +183,6 @@ typedef struct
bigint *qInv; /* q^-1 mod p */ bigint *qInv; /* q^-1 mod p */
#endif #endif
int num_octets; int num_octets;
bigint *sig_m; /* signature modulus */
BI_CTX *bi_ctx; BI_CTX *bi_ctx;
} RSA_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 RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data,
int is_decryption); int is_decryption);
bigint *RSA_private(const RSA_CTX *c, bigint *bi_msg); bigint *RSA_private(const RSA_CTX *c, bigint *bi_msg);
#ifdef CONFIG_SSL_CERT_VERIFICATION #if defined(CONFIG_SSL_CERT_VERIFICATION) || defined(CONFIG_SSL_GENERATE_X509_CERT)
bigint *RSA_raw_sign_verify(RSA_CTX *c, bigint *bi_msg);
bigint *RSA_sign_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len, bigint *RSA_sign_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
bigint *modulus, bigint *pub_exp); 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, int RSA_encrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len,
uint8_t *out_data, int is_signing); uint8_t *out_data, int is_signing);
void RSA_print(const RSA_CTX *ctx); void RSA_print(const RSA_CTX *ctx);
#endif #endif
/************************************************************************** /**************************************************************************
* ASN1 declarations * RNG declarations
**************************************************************************/ **************************************************************************/
#define X509_OK 0 EXP_FUNC void STDCALL RNG_initialize(const uint8_t *seed_buf, int size);
#define X509_NOT_OK -1 EXP_FUNC void STDCALL RNG_terminate(void);
#define X509_VFY_ERROR_NO_TRUSTED_CERT -2 EXP_FUNC void STDCALL get_random(int num_rand_bytes, uint8_t *rand_data);
#define X509_VFY_ERROR_BAD_SIGNATURE -3 void get_random_NZ(int num_rand_bytes, uint8_t *rand_data);
#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
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,61 +1,54 @@
#ifndef AXTLS_OS_PORT_H
#define AXTLS_OS_PORT_H
/** /**
* @file os_port.h * @file os_port.h
* *
* Trick the axtls code into building within our build environment. * Trick the axtls code into building within our build environment.
*/ */
#ifndef HEADER_OS_PORT_H
#define HEADER_OS_PORT_H
#include <stdint.h> #include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <byteswap.h> #include <byteswap.h>
#define STDCALL /** All imported axTLS files are licensed using the three-clause BSD licence */
#define EXP_FUNC FILE_LICENCE ( BSD3 );
#define TTY_FLUSH()
/** We can't actually abort, since we are effectively a kernel... */ /** We can't actually abort, since we are effectively a kernel... */
#define abort() assert ( 0 ) #define abort() assert ( 0 )
/** crypto_misc.c has a bad #ifdef */ /** rsa.c uses alloca() */
static inline void close ( int fd __unused ) { #define alloca( size ) __builtin_alloca ( size )
/* Do nothing */
#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, /* AES_CTX is not defined at this point, so omit prototypes */
const char *mode __unused ) {
return NULL; 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, void axtls_aes_decrypt ( void *ctx, uint32_t *data ) {
int whence __unused ) { AES_decrypt ( ctx, data );
return -1;
} }
static inline long ftell ( FILE *stream __unused ) { #endif
return -1; #undef aes
}
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 #endif

View File

@ -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 * All rights reserved.
* 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.
* *
* This library is distributed in the hope that it will be useful, * Redistribution and use in source and binary forms, with or without
* but WITHOUT ANY WARRANTY; without even the implied warranty of * modification, are permitted provided that the following conditions are met:
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * * Redistributions of source code must retain the above copyright notice,
* along with this library; if not, write to the Free Software * this list of conditions and the following disclaimer.
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * 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 <string.h>
#include <time.h> #include <time.h>
#include <stdlib.h> #include <stdlib.h>
#include "os_port.h"
#include "crypto.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, void RSA_priv_key_new(RSA_CTX **ctx,
const uint8_t *modulus, int mod_len, const uint8_t *modulus, int mod_len,
const uint8_t *pub_exp, int pub_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) const uint8_t *pub_exp, int pub_len)
{ {
RSA_CTX *rsa_ctx; 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)); *ctx = (RSA_CTX *)calloc(1, sizeof(RSA_CTX));
rsa_ctx = *ctx; rsa_ctx = *ctx;
rsa_ctx->bi_ctx = bi_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); rsa_ctx->m = bi_import(bi_ctx, modulus, mod_len);
bi_set_mod(bi_ctx, rsa_ctx->m, BIGINT_M_OFFSET); bi_set_mod(bi_ctx, rsa_ctx->m, BIGINT_M_OFFSET);
rsa_ctx->e = bi_import(bi_ctx, pub_exp, pub_len); 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, int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data,
uint8_t *out_data, int is_decryption) uint8_t *out_data, int is_decryption)
{ {
int byte_size = ctx->num_octets; const int byte_size = ctx->num_octets;
uint8_t *block;
int i, size; int i, size;
bigint *decrypted_bi, *dat_bi; bigint *decrypted_bi, *dat_bi;
uint8_t *block = (uint8_t *)alloca(byte_size);
memset(out_data, 0, byte_size); /* initialise */ memset(out_data, 0, byte_size); /* initialise */
@ -146,7 +160,6 @@ int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data,
#endif #endif
/* convert to a normal block */ /* convert to a normal block */
block = (uint8_t *)malloc(byte_size);
bi_export(ctx->bi_ctx, decrypted_bi, block, byte_size); bi_export(ctx->bi_ctx, decrypted_bi, block, byte_size);
i = 10; /* start at the first possible non-padded byte */ 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) if (size > 0)
memcpy(out_data, &block[i], size); memcpy(out_data, &block[i], size);
free(block);
return size ? size : -1; 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) bigint *RSA_private(const RSA_CTX *c, bigint *bi_msg)
{ {
#ifdef CONFIG_BIGINT_CRT #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 #else
BI_CTX *ctx = c->bi_ctx; BI_CTX *ctx = c->bi_ctx;
ctx->mod_offset = BIGINT_M_OFFSET; ctx->mod_offset = BIGINT_M_OFFSET;
@ -188,39 +200,6 @@ bigint *RSA_private(const RSA_CTX *c, bigint *bi_msg)
#endif #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 #ifdef CONFIG_SSL_FULL_MODE
/** /**
* Used for diagnostics. * Used for diagnostics.
@ -238,7 +217,7 @@ void RSA_print(const RSA_CTX *rsa_ctx)
} }
#endif #endif
#ifdef CONFIG_SSL_CERT_VERIFICATION #if defined(CONFIG_SSL_CERT_VERIFICATION) || defined(CONFIG_SSL_GENERATE_X509_CERT)
/** /**
* Performs c = m^e mod n * Performs c = m^e mod n
*/ */
@ -281,52 +260,10 @@ int RSA_encrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len,
encrypt_bi = is_signing ? RSA_private(ctx, dat_bi) : 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); 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; 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 */ #endif /* CONFIG_SSL_CERT_VERIFICATION */

View File

@ -20,6 +20,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <assert.h>
#include <byteswap.h> #include <byteswap.h>
#include <ipxe/crypto.h> #include <ipxe/crypto.h>
#include <ipxe/cbc.h> #include <ipxe/cbc.h>
@ -119,7 +120,7 @@ static void aes_encrypt ( void *ctx, const void *src, void *dst,
assert ( len == AES_BLOCKSIZE ); assert ( len == AES_BLOCKSIZE );
if ( aes_ctx->decrypting ) if ( aes_ctx->decrypting )
assert ( 0 ); 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_convert_key ( &aes_ctx->axtls_ctx );
aes_ctx->decrypting = 1; 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 */ /** Basic AES algorithm */

View File

@ -155,6 +155,11 @@ int x509_rsa_public_key ( const struct asn1_cursor *certificate,
DBG_HDA ( 0, certificate->data, certificate->len ); DBG_HDA ( 0, certificate->data, certificate->len );
return -ENOTSUP; return -ENOTSUP;
} }
if ( modulus.len && ( ! *( ( uint8_t * ) modulus.data ) ) ) {
/* Skip positive sign byte */
modulus.data++;
modulus.len--;
}
memcpy ( &exponent, &pubkey, sizeof ( exponent ) ); memcpy ( &exponent, &pubkey, sizeof ( exponent ) );
rc = ( asn1_skip ( &exponent, ASN1_INTEGER ), /* modulus */ rc = ( asn1_skip ( &exponent, ASN1_INTEGER ), /* modulus */
asn1_enter ( &exponent, ASN1_INTEGER ) /* publicExponent */ ); 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 ); DBG_HDA ( 0, certificate->data, certificate->len );
return -ENOTSUP; 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 */ /* Allocate space and copy out modulus and exponent */
rsa_pubkey->modulus = malloc ( modulus.len + exponent.len ); rsa_pubkey->modulus = malloc ( modulus.len + exponent.len );

View File

@ -21,6 +21,10 @@ struct aes_context {
/** AES context size */ /** AES context size */
#define AES_CTX_SIZE sizeof ( struct aes_context ) #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_algorithm;
extern struct cipher_algorithm aes_cbc_algorithm; extern struct cipher_algorithm aes_cbc_algorithm;

View File

@ -794,7 +794,7 @@ static int tls_send_certificate ( struct tls_session *tls ) {
*/ */
static int tls_send_client_key_exchange ( struct tls_session *tls ) { static int tls_send_client_key_exchange ( struct tls_session *tls ) {
/* FIXME: Hack alert */ /* 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, RSA_pub_key_new ( &rsa_ctx, tls->rsa.modulus, tls->rsa.modulus_len,
tls->rsa.exponent, tls->rsa.exponent_len ); tls->rsa.exponent, tls->rsa.exponent_len );
struct { struct {