]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[crypto] Upgrade AES and RSA code to upstream axTLS version 1.4.5
authorMichael Brown <mcb30@ipxe.org>
Fri, 9 Mar 2012 15:45:56 +0000 (15:45 +0000)
committerMichael Brown <mcb30@ipxe.org>
Fri, 9 Mar 2012 17:14:39 +0000 (17:14 +0000)
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>
12 files changed:
src/crypto/axtls/aes.c
src/crypto/axtls/bigint.c
src/crypto/axtls/bigint.h
src/crypto/axtls/bigint_impl.h
src/crypto/axtls/config.h [new file with mode: 0644]
src/crypto/axtls/crypto.h
src/crypto/axtls/os_port.h
src/crypto/axtls/rsa.c
src/crypto/axtls_aes.c
src/crypto/x509.c
src/include/ipxe/aes.h
src/net/tls.c

index 87faaa1d2f30500334ee61452330f96452a1eed5..bd99a7097cc60ca5f167dd890aa71f2c933c5d55 100644 (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
- *  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;
-
-    n2l(iv, tout0);
-    n2l(iv, tout1);
-    n2l(iv, tout2);
-    n2l(iv, tout3);
-    iv -= 4;
+    int i;
+    uint32_t tin[4], tout[4], iv[4];
 
-    for (length -= 16; length >= 0; length -= 16)
+    memcpy(iv, ctx->iv, AES_IV_SIZE);
+    for (i = 0; i < 4; i++)
+        tout[i] = ntohl(iv[i]);
+
+    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;
-
-    n2l(iv ,xor0);
-    n2l(iv, xor1);
-    n2l(iv, xor2);
-    n2l(iv, xor3);
-    iv -= 4;
-
-    for (length-=16; length >= 0; length -= 16)
+    int i;
+    uint32_t tin[4], xor[4], tout[4], data[4], 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)
     {
-        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;
-
-        xor0 = tin0;
-        xor1 = tin1;
-        xor2 = tin2;
-        xor3 = tin3;
+        for (i = 0; i < 4; i++)
+        {
+            tout[i] = data[i]^xor[i];
+            xor[i] = tin[i];
+            out_32[i] = htonl(tout[i]);
+        }
 
-        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);
-        }
     }
 }
 
index 49cad971e9e28e88e79907e318c621ebdce241f5..e228a218e276eabba77d4b7854b5640daeecb2ea 100644 (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
- *  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.
  */
 
 /**
 #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;
-            w[i+j] = (comp)tmp;
-            carry = (comp)(tmp >> COMP_BIT_SIZE);
-        }
+            tmp += w[i+j];
 
-        w[i+t] += carry;
+            if ((COMP_MAX-tmp) < carry)
+                c = 1;
 
-        if (u)
-        {
-            w[i+t+1] = 1;   /* add carry */
+            tmp += carry;
+            w[i+j] = (comp)tmp;
+            carry = tmp >> COMP_BIT_SIZE;
+
+            if (c)
+                carry += COMP_RADIX;
         }
+
+        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
 /** @} */
index f5f3353110735c9d993ce1abaee224efbd9199f8..1f38c53d63adac8d0d198b61a219e9575a909cf3 100644 (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
- *  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 "os_port.h"
-#include "bigint_impl.h"
+#include "crypto.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
index 762a7ccbb2754fc6e4ecf86238262e2dd10df44c..09d8550ea2c4be851d01860e9aa26d9c45cddb71 100644 (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
- *  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
 #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
diff --git a/src/crypto/axtls/config.h b/src/crypto/axtls/config.h
new file mode 100644 (file)
index 0000000..32fa3bf
--- /dev/null
@@ -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
index b7af7c419ed6ae0d51590888ced27b0d349535a6..2c4cda4de4afc3694b078f3cee422751a51a1366 100644 (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
- *  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 
- **************************************************************************/
-#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 
+ * RNG 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
 }
index babdbfad833862ca9c093a71940e2de2c9e62b94..0a6ef54a9bbfcf722b98b2be97a793c84de50c6b 100644 (file)
@@ -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;
-
-static inline FILE * fopen ( const char *filename __unused,
-                            const char *mode __unused ) {
-       return NULL;
-}
+/* Expose AES_encrypt() and AES_decrypt() in aes.o */
+#define aes 1
+#if OBJECT
 
-static inline int fseek ( FILE *stream __unused, long offset __unused,
-                         int whence __unused ) {
-       return -1;
-}
+/* AES_CTX is not defined at this point, so omit prototypes */
 
-static inline long ftell ( FILE *stream __unused ) {
-       return -1;
-}
+static void AES_encrypt();
+static void AES_decrypt();
 
-static inline size_t fread ( void *ptr __unused, size_t size __unused,
-                            size_t nmemb __unused, FILE *stream __unused ) {
-       return -1;
+void axtls_aes_encrypt ( void *ctx, uint32_t *data ) {
+       AES_encrypt ( ctx, data );
 }
 
-static inline int fclose ( FILE *stream __unused ) {
-       return -1;
+void axtls_aes_decrypt ( void *ctx, uint32_t *data ) {
+       AES_decrypt ( ctx, data );
 }
 
-#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 
index 389eda577818aa8d2c596663ed88c6562a4e3b44..f17500c3c7550d479b7e9a09f950bd5a0408c3a1 100644 (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
- *  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.
  */
 
 /**
 #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);
-    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;
+    /* save a few bytes of memory */
+    bi_clear_cache(ctx->bi_ctx);
+    return byte_size;
 }
-#endif
 
 #endif  /* CONFIG_SSL_CERT_VERIFICATION */
index b73a572526f12eb27e57c40c4931ef135c5971dd..3f1d668a92713e2ea63af80cfde1f3cc96e499e7 100644 (file)
@@ -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 */
index 28d28fc14ffbea617fc9a0006195c20a9fb704a0..50593bc6dbe9371f6c538b98c59f173de0272c36 100644 (file)
@@ -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 );
index 5d645b207f706aef0de670aa838fd51254c2106c..4e44f9853671d87a72197a21a47181d759cf2fa5 100644 (file)
@@ -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;
 
index 8940613c3a57d5496f4697b8dddc3e3ecc7c2b71..90af1676577c9d37af0af69bac344962bf113e61 100644 (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 ) {
        /* 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 {