summaryrefslogtreecommitdiffhomepage
path: root/libs/luci-lib-px5g/src/polarssl
diff options
context:
space:
mode:
Diffstat (limited to 'libs/luci-lib-px5g/src/polarssl')
-rw-r--r--libs/luci-lib-px5g/src/polarssl/bignum.h437
-rw-r--r--libs/luci-lib-px5g/src/polarssl/bn_mul.h731
-rw-r--r--libs/luci-lib-px5g/src/polarssl/config.h329
-rw-r--r--libs/luci-lib-px5g/src/polarssl/havege.h75
-rw-r--r--libs/luci-lib-px5g/src/polarssl/rsa.h309
-rw-r--r--libs/luci-lib-px5g/src/polarssl/sha1.h150
-rw-r--r--libs/luci-lib-px5g/src/polarssl/timing.h81
-rw-r--r--libs/luci-lib-px5g/src/polarssl/x509.h549
8 files changed, 2661 insertions, 0 deletions
diff --git a/libs/luci-lib-px5g/src/polarssl/bignum.h b/libs/luci-lib-px5g/src/polarssl/bignum.h
new file mode 100644
index 0000000000..c667303329
--- /dev/null
+++ b/libs/luci-lib-px5g/src/polarssl/bignum.h
@@ -0,0 +1,437 @@
+/**
+ * \file bignum.h
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * 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 names of PolarSSL or XySSL 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 POLARSSL_BIGNUM_H
+#define POLARSSL_BIGNUM_H
+
+#include <stdio.h>
+
+#define POLARSSL_ERR_MPI_FILE_IO_ERROR -0x0002
+#define POLARSSL_ERR_MPI_BAD_INPUT_DATA -0x0004
+#define POLARSSL_ERR_MPI_INVALID_CHARACTER -0x0006
+#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL -0x0008
+#define POLARSSL_ERR_MPI_NEGATIVE_VALUE -0x000A
+#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO -0x000C
+#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE -0x000E
+
+#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup
+
+/*
+ * Define the base integer type, architecture-wise
+ */
+#if defined(POLARSSL_HAVE_INT8)
+typedef unsigned char t_int;
+typedef unsigned short t_dbl;
+#else
+#if defined(POLARSSL_HAVE_INT16)
+typedef unsigned short t_int;
+typedef unsigned long t_dbl;
+#else
+ typedef unsigned long t_int;
+ #if defined(_MSC_VER) && defined(_M_IX86)
+ typedef unsigned __int64 t_dbl;
+ #else
+ #if defined(__amd64__) || defined(__x86_64__) || \
+ defined(__ppc64__) || defined(__powerpc64__) || \
+ defined(__ia64__) || defined(__alpha__)
+ typedef unsigned int t_dbl __attribute__((mode(TI)));
+ #else
+ typedef unsigned long long t_dbl;
+ #endif
+ #endif
+#endif
+#endif
+
+/**
+ * \brief MPI structure
+ */
+typedef struct
+{
+ int s; /*!< integer sign */
+ int n; /*!< total # of limbs */
+ t_int *p; /*!< pointer to limbs */
+}
+mpi;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Initialize one or more mpi
+ */
+void mpi_init( mpi *X, ... );
+
+/**
+ * \brief Unallocate one or more mpi
+ */
+void mpi_free( mpi *X, ... );
+
+/**
+ * \brief Enlarge to the specified number of limbs
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_grow( mpi *X, int nblimbs );
+
+/**
+ * \brief Copy the contents of Y into X
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_copy( mpi *X, mpi *Y );
+
+/**
+ * \brief Swap the contents of X and Y
+ */
+void mpi_swap( mpi *X, mpi *Y );
+
+/**
+ * \brief Set value from integer
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_lset( mpi *X, int z );
+
+/**
+ * \brief Return the number of least significant bits
+ */
+int mpi_lsb( mpi *X );
+
+/**
+ * \brief Return the number of most significant bits
+ */
+int mpi_msb( mpi *X );
+
+/**
+ * \brief Return the total size in bytes
+ */
+int mpi_size( mpi *X );
+
+/**
+ * \brief Import from an ASCII string
+ *
+ * \param X destination mpi
+ * \param radix input numeric base
+ * \param s null-terminated string buffer
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
+ */
+int mpi_read_string( mpi *X, int radix, char *s );
+
+/**
+ * \brief Export into an ASCII string
+ *
+ * \param X source mpi
+ * \param radix output numeric base
+ * \param s string buffer
+ * \param slen string buffer size
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
+ *
+ * \note Call this function with *slen = 0 to obtain the
+ * minimum required buffer size in *slen.
+ */
+int mpi_write_string( mpi *X, int radix, char *s, int *slen );
+
+/**
+ * \brief Read X from an opened file
+ *
+ * \param X destination mpi
+ * \param radix input numeric base
+ * \param fin input file handle
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
+ */
+int mpi_read_file( mpi *X, int radix, FILE *fin );
+
+/**
+ * \brief Write X into an opened file, or stdout
+ *
+ * \param p prefix, can be NULL
+ * \param X source mpi
+ * \param radix output numeric base
+ * \param fout output file handle
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
+ *
+ * \note Set fout == NULL to print X on the console.
+ */
+int mpi_write_file( char *p, mpi *X, int radix, FILE *fout );
+
+/**
+ * \brief Import X from unsigned binary data, big endian
+ *
+ * \param X destination mpi
+ * \param buf input buffer
+ * \param buflen input buffer size
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_read_binary( mpi *X, unsigned char *buf, int buflen );
+
+/**
+ * \brief Export X into unsigned binary data, big endian
+ *
+ * \param X source mpi
+ * \param buf output buffer
+ * \param buflen output buffer size
+ *
+ * \return 0 if successful,
+ * POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
+ *
+ * \note Call this function with *buflen = 0 to obtain the
+ * minimum required buffer size in *buflen.
+ */
+int mpi_write_binary( mpi *X, unsigned char *buf, int buflen );
+
+/**
+ * \brief Left-shift: X <<= count
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_shift_l( mpi *X, int count );
+
+/**
+ * \brief Right-shift: X >>= count
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_shift_r( mpi *X, int count );
+
+/**
+ * \brief Compare unsigned values
+ *
+ * \return 1 if |X| is greater than |Y|,
+ * -1 if |X| is lesser than |Y| or
+ * 0 if |X| is equal to |Y|
+ */
+int mpi_cmp_abs( mpi *X, mpi *Y );
+
+/**
+ * \brief Compare signed values
+ *
+ * \return 1 if X is greater than Y,
+ * -1 if X is lesser than Y or
+ * 0 if X is equal to Y
+ */
+int mpi_cmp_mpi( mpi *X, mpi *Y );
+
+/**
+ * \brief Compare signed values
+ *
+ * \return 1 if X is greater than z,
+ * -1 if X is lesser than z or
+ * 0 if X is equal to z
+ */
+int mpi_cmp_int( mpi *X, int z );
+
+/**
+ * \brief Unsigned addition: X = |A| + |B|
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_add_abs( mpi *X, mpi *A, mpi *B );
+
+/**
+ * \brief Unsigned substraction: X = |A| - |B|
+ *
+ * \return 0 if successful,
+ * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A
+ */
+int mpi_sub_abs( mpi *X, mpi *A, mpi *B );
+
+/**
+ * \brief Signed addition: X = A + B
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_add_mpi( mpi *X, mpi *A, mpi *B );
+
+/**
+ * \brief Signed substraction: X = A - B
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_sub_mpi( mpi *X, mpi *A, mpi *B );
+
+/**
+ * \brief Signed addition: X = A + b
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_add_int( mpi *X, mpi *A, int b );
+
+/**
+ * \brief Signed substraction: X = A - b
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_sub_int( mpi *X, mpi *A, int b );
+
+/**
+ * \brief Baseline multiplication: X = A * B
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_mul_mpi( mpi *X, mpi *A, mpi *B );
+
+/**
+ * \brief Baseline multiplication: X = A * b
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_mul_int( mpi *X, mpi *A, t_int b );
+
+/**
+ * \brief Division by mpi: A = Q * B + R
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
+ *
+ * \note Either Q or R can be NULL.
+ */
+int mpi_div_mpi( mpi *Q, mpi *R, mpi *A, mpi *B );
+
+/**
+ * \brief Division by int: A = Q * b + R
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
+ *
+ * \note Either Q or R can be NULL.
+ */
+int mpi_div_int( mpi *Q, mpi *R, mpi *A, int b );
+
+/**
+ * \brief Modulo: R = A mod B
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
+ */
+int mpi_mod_mpi( mpi *R, mpi *A, mpi *B );
+
+/**
+ * \brief Modulo: r = A mod b
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
+ */
+int mpi_mod_int( t_int *r, mpi *A, int b );
+
+/**
+ * \brief Sliding-window exponentiation: X = A^E mod N
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even
+ *
+ * \note _RR is used to avoid re-computing R*R mod N across
+ * multiple calls, which speeds up things a bit. It can
+ * be set to NULL if the extra performance is unneeded.
+ */
+int mpi_exp_mod( mpi *X, mpi *A, mpi *E, mpi *N, mpi *_RR );
+
+/**
+ * \brief Greatest common divisor: G = gcd(A, B)
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_gcd( mpi *G, mpi *A, mpi *B );
+
+/**
+ * \brief Modular inverse: X = A^-1 mod N
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
+ * POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
+ */
+int mpi_inv_mod( mpi *X, mpi *A, mpi *N );
+
+/**
+ * \brief Miller-Rabin primality test
+ *
+ * \return 0 if successful (probably prime),
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime
+ */
+int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng );
+
+/**
+ * \brief Prime number generation
+ *
+ * \param X destination mpi
+ * \param nbits required size of X in bits
+ * \param dh_flag if 1, then (X-1)/2 will be prime too
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
+ *
+ * \return 0 if successful (probably prime),
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
+ */
+int mpi_gen_prime( mpi *X, int nbits, int dh_flag,
+ int (*f_rng)(void *), void *p_rng );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int mpi_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* bignum.h */
diff --git a/libs/luci-lib-px5g/src/polarssl/bn_mul.h b/libs/luci-lib-px5g/src/polarssl/bn_mul.h
new file mode 100644
index 0000000000..f6d34da58a
--- /dev/null
+++ b/libs/luci-lib-px5g/src/polarssl/bn_mul.h
@@ -0,0 +1,731 @@
+/**
+ * \file bn_mul.h
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * 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 names of PolarSSL or XySSL 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.
+ */
+/*
+ * Multiply source vector [s] with b, add result
+ * to destination vector [d] and set carry c.
+ *
+ * Currently supports:
+ *
+ * . IA-32 (386+) . AMD64 / EM64T
+ * . IA-32 (SSE2) . Motorola 68000
+ * . PowerPC, 32-bit . MicroBlaze
+ * . PowerPC, 64-bit . TriCore
+ * . SPARC v8 . ARM v3+
+ * . Alpha . MIPS32
+ * . C, longlong . C, generic
+ */
+#ifndef POLARSSL_BN_MUL_H
+#define POLARSSL_BN_MUL_H
+
+#include "polarssl/config.h"
+
+#if defined(POLARSSL_HAVE_ASM)
+
+#if defined(__GNUC__)
+#if defined(__i386__)
+
+#define MULADDC_INIT \
+ asm( "movl %%ebx, %0 " : "=m" (t)); \
+ asm( "movl %0, %%esi " :: "m" (s)); \
+ asm( "movl %0, %%edi " :: "m" (d)); \
+ asm( "movl %0, %%ecx " :: "m" (c)); \
+ asm( "movl %0, %%ebx " :: "m" (b));
+
+#define MULADDC_CORE \
+ asm( "lodsl " ); \
+ asm( "mull %ebx " ); \
+ asm( "addl %ecx, %eax " ); \
+ asm( "adcl $0, %edx " ); \
+ asm( "addl (%edi), %eax " ); \
+ asm( "adcl $0, %edx " ); \
+ asm( "movl %edx, %ecx " ); \
+ asm( "stosl " );
+
+#if defined(POLARSSL_HAVE_SSE2)
+
+#define MULADDC_HUIT \
+ asm( "movd %ecx, %mm1 " ); \
+ asm( "movd %ebx, %mm0 " ); \
+ asm( "movd (%edi), %mm3 " ); \
+ asm( "paddq %mm3, %mm1 " ); \
+ asm( "movd (%esi), %mm2 " ); \
+ asm( "pmuludq %mm0, %mm2 " ); \
+ asm( "movd 4(%esi), %mm4 " ); \
+ asm( "pmuludq %mm0, %mm4 " ); \
+ asm( "movd 8(%esi), %mm6 " ); \
+ asm( "pmuludq %mm0, %mm6 " ); \
+ asm( "movd 12(%esi), %mm7 " ); \
+ asm( "pmuludq %mm0, %mm7 " ); \
+ asm( "paddq %mm2, %mm1 " ); \
+ asm( "movd 4(%edi), %mm3 " ); \
+ asm( "paddq %mm4, %mm3 " ); \
+ asm( "movd 8(%edi), %mm5 " ); \
+ asm( "paddq %mm6, %mm5 " ); \
+ asm( "movd 12(%edi), %mm4 " ); \
+ asm( "paddq %mm4, %mm7 " ); \
+ asm( "movd %mm1, (%edi) " ); \
+ asm( "movd 16(%esi), %mm2 " ); \
+ asm( "pmuludq %mm0, %mm2 " ); \
+ asm( "psrlq $32, %mm1 " ); \
+ asm( "movd 20(%esi), %mm4 " ); \
+ asm( "pmuludq %mm0, %mm4 " ); \
+ asm( "paddq %mm3, %mm1 " ); \
+ asm( "movd 24(%esi), %mm6 " ); \
+ asm( "pmuludq %mm0, %mm6 " ); \
+ asm( "movd %mm1, 4(%edi) " ); \
+ asm( "psrlq $32, %mm1 " ); \
+ asm( "movd 28(%esi), %mm3 " ); \
+ asm( "pmuludq %mm0, %mm3 " ); \
+ asm( "paddq %mm5, %mm1 " ); \
+ asm( "movd 16(%edi), %mm5 " ); \
+ asm( "paddq %mm5, %mm2 " ); \
+ asm( "movd %mm1, 8(%edi) " ); \
+ asm( "psrlq $32, %mm1 " ); \
+ asm( "paddq %mm7, %mm1 " ); \
+ asm( "movd 20(%edi), %mm5 " ); \
+ asm( "paddq %mm5, %mm4 " ); \
+ asm( "movd %mm1, 12(%edi) " ); \
+ asm( "psrlq $32, %mm1 " ); \
+ asm( "paddq %mm2, %mm1 " ); \
+ asm( "movd 24(%edi), %mm5 " ); \
+ asm( "paddq %mm5, %mm6 " ); \
+ asm( "movd %mm1, 16(%edi) " ); \
+ asm( "psrlq $32, %mm1 " ); \
+ asm( "paddq %mm4, %mm1 " ); \
+ asm( "movd 28(%edi), %mm5 " ); \
+ asm( "paddq %mm5, %mm3 " ); \
+ asm( "movd %mm1, 20(%edi) " ); \
+ asm( "psrlq $32, %mm1 " ); \
+ asm( "paddq %mm6, %mm1 " ); \
+ asm( "movd %mm1, 24(%edi) " ); \
+ asm( "psrlq $32, %mm1 " ); \
+ asm( "paddq %mm3, %mm1 " ); \
+ asm( "movd %mm1, 28(%edi) " ); \
+ asm( "addl $32, %edi " ); \
+ asm( "addl $32, %esi " ); \
+ asm( "psrlq $32, %mm1 " ); \
+ asm( "movd %mm1, %ecx " );
+
+#define MULADDC_STOP \
+ asm( "emms " ); \
+ asm( "movl %0, %%ebx " :: "m" (t)); \
+ asm( "movl %%ecx, %0 " : "=m" (c)); \
+ asm( "movl %%edi, %0 " : "=m" (d)); \
+ asm( "movl %%esi, %0 " : "=m" (s) :: \
+ "eax", "ecx", "edx", "esi", "edi" );
+
+#else
+
+#define MULADDC_STOP \
+ asm( "movl %0, %%ebx " :: "m" (t)); \
+ asm( "movl %%ecx, %0 " : "=m" (c)); \
+ asm( "movl %%edi, %0 " : "=m" (d)); \
+ asm( "movl %%esi, %0 " : "=m" (s) :: \
+ "eax", "ecx", "edx", "esi", "edi" );
+
+#endif /* SSE2 */
+#endif /* i386 */
+
+#if defined(__amd64__) || defined (__x86_64__)
+
+#define MULADDC_INIT \
+ asm( "movq %0, %%rsi " :: "m" (s)); \
+ asm( "movq %0, %%rdi " :: "m" (d)); \
+ asm( "movq %0, %%rcx " :: "m" (c)); \
+ asm( "movq %0, %%rbx " :: "m" (b)); \
+ asm( "xorq %r8, %r8 " );
+
+#define MULADDC_CORE \
+ asm( "movq (%rsi),%rax " ); \
+ asm( "mulq %rbx " ); \
+ asm( "addq $8, %rsi " ); \
+ asm( "addq %rcx, %rax " ); \
+ asm( "movq %r8, %rcx " ); \
+ asm( "adcq $0, %rdx " ); \
+ asm( "nop " ); \
+ asm( "addq %rax, (%rdi) " ); \
+ asm( "adcq %rdx, %rcx " ); \
+ asm( "addq $8, %rdi " );
+
+#define MULADDC_STOP \
+ asm( "movq %%rcx, %0 " : "=m" (c)); \
+ asm( "movq %%rdi, %0 " : "=m" (d)); \
+ asm( "movq %%rsi, %0 " : "=m" (s) :: \
+ "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" );
+
+#endif /* AMD64 */
+
+#if defined(__mc68020__) || defined(__mcpu32__)
+
+#define MULADDC_INIT \
+ asm( "movl %0, %%a2 " :: "m" (s)); \
+ asm( "movl %0, %%a3 " :: "m" (d)); \
+ asm( "movl %0, %%d3 " :: "m" (c)); \
+ asm( "movl %0, %%d2 " :: "m" (b)); \
+ asm( "moveq #0, %d0 " );
+
+#define MULADDC_CORE \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d4:%d1 " ); \
+ asm( "addl %d3, %d1 " ); \
+ asm( "addxl %d0, %d4 " ); \
+ asm( "moveq #0, %d3 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "addxl %d4, %d3 " );
+
+#define MULADDC_STOP \
+ asm( "movl %%d3, %0 " : "=m" (c)); \
+ asm( "movl %%a3, %0 " : "=m" (d)); \
+ asm( "movl %%a2, %0 " : "=m" (s) :: \
+ "d0", "d1", "d2", "d3", "d4", "a2", "a3" );
+
+#define MULADDC_HUIT \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d4:%d1 " ); \
+ asm( "addxl %d3, %d1 " ); \
+ asm( "addxl %d0, %d4 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d3:%d1 " ); \
+ asm( "addxl %d4, %d1 " ); \
+ asm( "addxl %d0, %d3 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d4:%d1 " ); \
+ asm( "addxl %d3, %d1 " ); \
+ asm( "addxl %d0, %d4 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d3:%d1 " ); \
+ asm( "addxl %d4, %d1 " ); \
+ asm( "addxl %d0, %d3 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d4:%d1 " ); \
+ asm( "addxl %d3, %d1 " ); \
+ asm( "addxl %d0, %d4 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d3:%d1 " ); \
+ asm( "addxl %d4, %d1 " ); \
+ asm( "addxl %d0, %d3 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d4:%d1 " ); \
+ asm( "addxl %d3, %d1 " ); \
+ asm( "addxl %d0, %d4 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d3:%d1 " ); \
+ asm( "addxl %d4, %d1 " ); \
+ asm( "addxl %d0, %d3 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "addxl %d0, %d3 " );
+
+#endif /* MC68000 */
+
+#if defined(__powerpc__) || defined(__ppc__)
+#if defined(__powerpc64__) || defined(__ppc64__)
+
+#if defined(__MACH__) && defined(__APPLE__)
+
+#define MULADDC_INIT \
+ asm( "ld r3, %0 " :: "m" (s)); \
+ asm( "ld r4, %0 " :: "m" (d)); \
+ asm( "ld r5, %0 " :: "m" (c)); \
+ asm( "ld r6, %0 " :: "m" (b)); \
+ asm( "addi r3, r3, -8 " ); \
+ asm( "addi r4, r4, -8 " ); \
+ asm( "addic r5, r5, 0 " );
+
+#define MULADDC_CORE \
+ asm( "ldu r7, 8(r3) " ); \
+ asm( "mulld r8, r7, r6 " ); \
+ asm( "mulhdu r9, r7, r6 " ); \
+ asm( "adde r8, r8, r5 " ); \
+ asm( "ld r7, 8(r4) " ); \
+ asm( "addze r5, r9 " ); \
+ asm( "addc r8, r8, r7 " ); \
+ asm( "stdu r8, 8(r4) " );
+
+#define MULADDC_STOP \
+ asm( "addze r5, r5 " ); \
+ asm( "addi r4, r4, 8 " ); \
+ asm( "addi r3, r3, 8 " ); \
+ asm( "std r5, %0 " : "=m" (c)); \
+ asm( "std r4, %0 " : "=m" (d)); \
+ asm( "std r3, %0 " : "=m" (s) :: \
+ "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
+
+#else
+
+#define MULADDC_INIT \
+ asm( "ld %%r3, %0 " :: "m" (s)); \
+ asm( "ld %%r4, %0 " :: "m" (d)); \
+ asm( "ld %%r5, %0 " :: "m" (c)); \
+ asm( "ld %%r6, %0 " :: "m" (b)); \
+ asm( "addi %r3, %r3, -8 " ); \
+ asm( "addi %r4, %r4, -8 " ); \
+ asm( "addic %r5, %r5, 0 " );
+
+#define MULADDC_CORE \
+ asm( "ldu %r7, 8(%r3) " ); \
+ asm( "mulld %r8, %r7, %r6 " ); \
+ asm( "mulhdu %r9, %r7, %r6 " ); \
+ asm( "adde %r8, %r8, %r5 " ); \
+ asm( "ld %r7, 8(%r4) " ); \
+ asm( "addze %r5, %r9 " ); \
+ asm( "addc %r8, %r8, %r7 " ); \
+ asm( "stdu %r8, 8(%r4) " );
+
+#define MULADDC_STOP \
+ asm( "addze %r5, %r5 " ); \
+ asm( "addi %r4, %r4, 8 " ); \
+ asm( "addi %r3, %r3, 8 " ); \
+ asm( "std %%r5, %0 " : "=m" (c)); \
+ asm( "std %%r4, %0 " : "=m" (d)); \
+ asm( "std %%r3, %0 " : "=m" (s) :: \
+ "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
+
+#endif
+
+#else /* PPC32 */
+
+#if defined(__MACH__) && defined(__APPLE__)
+
+#define MULADDC_INIT \
+ asm( "lwz r3, %0 " :: "m" (s)); \
+ asm( "lwz r4, %0 " :: "m" (d)); \
+ asm( "lwz r5, %0 " :: "m" (c)); \
+ asm( "lwz r6, %0 " :: "m" (b)); \
+ asm( "addi r3, r3, -4 " ); \
+ asm( "addi r4, r4, -4 " ); \
+ asm( "addic r5, r5, 0 " );
+
+#define MULADDC_CORE \
+ asm( "lwzu r7, 4(r3) " ); \
+ asm( "mullw r8, r7, r6 " ); \
+ asm( "mulhwu r9, r7, r6 " ); \
+ asm( "adde r8, r8, r5 " ); \
+ asm( "lwz r7, 4(r4) " ); \
+ asm( "addze r5, r9 " ); \
+ asm( "addc r8, r8, r7 " ); \
+ asm( "stwu r8, 4(r4) " );
+
+#define MULADDC_STOP \
+ asm( "addze r5, r5 " ); \
+ asm( "addi r4, r4, 4 " ); \
+ asm( "addi r3, r3, 4 " ); \
+ asm( "stw r5, %0 " : "=m" (c)); \
+ asm( "stw r4, %0 " : "=m" (d)); \
+ asm( "stw r3, %0 " : "=m" (s) :: \
+ "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
+
+#else
+
+#define MULADDC_INIT \
+ asm( "lwz %%r3, %0 " :: "m" (s)); \
+ asm( "lwz %%r4, %0 " :: "m" (d)); \
+ asm( "lwz %%r5, %0 " :: "m" (c)); \
+ asm( "lwz %%r6, %0 " :: "m" (b)); \
+ asm( "addi %r3, %r3, -4 " ); \
+ asm( "addi %r4, %r4, -4 " ); \
+ asm( "addic %r5, %r5, 0 " );
+
+#define MULADDC_CORE \
+ asm( "lwzu %r7, 4(%r3) " ); \
+ asm( "mullw %r8, %r7, %r6 " ); \
+ asm( "mulhwu %r9, %r7, %r6 " ); \
+ asm( "adde %r8, %r8, %r5 " ); \
+ asm( "lwz %r7, 4(%r4) " ); \
+ asm( "addze %r5, %r9 " ); \
+ asm( "addc %r8, %r8, %r7 " ); \
+ asm( "stwu %r8, 4(%r4) " );
+
+#define MULADDC_STOP \
+ asm( "addze %r5, %r5 " ); \
+ asm( "addi %r4, %r4, 4 " ); \
+ asm( "addi %r3, %r3, 4 " ); \
+ asm( "stw %%r5, %0 " : "=m" (c)); \
+ asm( "stw %%r4, %0 " : "=m" (d)); \
+ asm( "stw %%r3, %0 " : "=m" (s) :: \
+ "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
+
+#endif
+
+#endif /* PPC32 */
+#endif /* PPC64 */
+
+#if defined(__sparc__)
+
+#define MULADDC_INIT \
+ asm( "ld %0, %%o0 " :: "m" (s)); \
+ asm( "ld %0, %%o1 " :: "m" (d)); \
+ asm( "ld %0, %%o2 " :: "m" (c)); \
+ asm( "ld %0, %%o3 " :: "m" (b));
+
+#define MULADDC_CORE \
+ asm( "ld [%o0], %o4 " ); \
+ asm( "inc 4, %o0 " ); \
+ asm( "ld [%o1], %o5 " ); \
+ asm( "umul %o3, %o4, %o4 " ); \
+ asm( "addcc %o4, %o2, %o4 " ); \
+ asm( "rd %y, %g1 " ); \
+ asm( "addx %g1, 0, %g1 " ); \
+ asm( "addcc %o4, %o5, %o4 " ); \
+ asm( "st %o4, [%o1] " ); \
+ asm( "addx %g1, 0, %o2 " ); \
+ asm( "inc 4, %o1 " );
+
+#define MULADDC_STOP \
+ asm( "st %%o2, %0 " : "=m" (c)); \
+ asm( "st %%o1, %0 " : "=m" (d)); \
+ asm( "st %%o0, %0 " : "=m" (s) :: \
+ "g1", "o0", "o1", "o2", "o3", "o4", "o5" );
+
+#endif /* SPARCv8 */
+
+#if defined(__microblaze__) || defined(microblaze)
+
+#define MULADDC_INIT \
+ asm( "lwi r3, %0 " :: "m" (s)); \
+ asm( "lwi r4, %0 " :: "m" (d)); \
+ asm( "lwi r5, %0 " :: "m" (c)); \
+ asm( "lwi r6, %0 " :: "m" (b)); \
+ asm( "andi r7, r6, 0xffff" ); \
+ asm( "bsrli r6, r6, 16 " );
+
+#define MULADDC_CORE \
+ asm( "lhui r8, r3, 0 " ); \
+ asm( "addi r3, r3, 2 " ); \
+ asm( "lhui r9, r3, 0 " ); \
+ asm( "addi r3, r3, 2 " ); \
+ asm( "mul r10, r9, r6 " ); \
+ asm( "mul r11, r8, r7 " ); \
+ asm( "mul r12, r9, r7 " ); \
+ asm( "mul r13, r8, r6 " ); \
+ asm( "bsrli r8, r10, 16 " ); \
+ asm( "bsrli r9, r11, 16 " ); \
+ asm( "add r13, r13, r8 " ); \
+ asm( "add r13, r13, r9 " ); \
+ asm( "bslli r10, r10, 16 " ); \
+ asm( "bslli r11, r11, 16 " ); \
+ asm( "add r12, r12, r10 " ); \
+ asm( "addc r13, r13, r0 " ); \
+ asm( "add r12, r12, r11 " ); \
+ asm( "addc r13, r13, r0 " ); \
+ asm( "lwi r10, r4, 0 " ); \
+ asm( "add r12, r12, r10 " ); \
+ asm( "addc r13, r13, r0 " ); \
+ asm( "add r12, r12, r5 " ); \
+ asm( "addc r5, r13, r0 " ); \
+ asm( "swi r12, r4, 0 " ); \
+ asm( "addi r4, r4, 4 " );
+
+#define MULADDC_STOP \
+ asm( "swi r5, %0 " : "=m" (c)); \
+ asm( "swi r4, %0 " : "=m" (d)); \
+ asm( "swi r3, %0 " : "=m" (s) :: \
+ "r3", "r4" , "r5" , "r6" , "r7" , "r8" , \
+ "r9", "r10", "r11", "r12", "r13" );
+
+#endif /* MicroBlaze */
+
+#if defined(__tricore__)
+
+#define MULADDC_INIT \
+ asm( "ld.a %%a2, %0 " :: "m" (s)); \
+ asm( "ld.a %%a3, %0 " :: "m" (d)); \
+ asm( "ld.w %%d4, %0 " :: "m" (c)); \
+ asm( "ld.w %%d1, %0 " :: "m" (b)); \
+ asm( "xor %d5, %d5 " );
+
+#define MULADDC_CORE \
+ asm( "ld.w %d0, [%a2+] " ); \
+ asm( "madd.u %e2, %e4, %d0, %d1 " ); \
+ asm( "ld.w %d0, [%a3] " ); \
+ asm( "addx %d2, %d2, %d0 " ); \
+ asm( "addc %d3, %d3, 0 " ); \
+ asm( "mov %d4, %d3 " ); \
+ asm( "st.w [%a3+], %d2 " );
+
+#define MULADDC_STOP \
+ asm( "st.w %0, %%d4 " : "=m" (c)); \
+ asm( "st.a %0, %%a3 " : "=m" (d)); \
+ asm( "st.a %0, %%a2 " : "=m" (s) :: \
+ "d0", "d1", "e2", "d4", "a2", "a3" );
+
+#endif /* TriCore */
+
+#if defined(__arm__)
+
+#define MULADDC_INIT \
+ asm( "ldr r0, %0 " :: "m" (s)); \
+ asm( "ldr r1, %0 " :: "m" (d)); \
+ asm( "ldr r2, %0 " :: "m" (c)); \
+ asm( "ldr r3, %0 " :: "m" (b));
+
+#define MULADDC_CORE \
+ asm( "ldr r4, [r0], #4 " ); \
+ asm( "mov r5, #0 " ); \
+ asm( "ldr r6, [r1] " ); \
+ asm( "umlal r2, r5, r3, r4 " ); \
+ asm( "adds r7, r6, r2 " ); \
+ asm( "adc r2, r5, #0 " ); \
+ asm( "str r7, [r1], #4 " );
+
+#define MULADDC_STOP \
+ asm( "str r2, %0 " : "=m" (c)); \
+ asm( "str r1, %0 " : "=m" (d)); \
+ asm( "str r0, %0 " : "=m" (s) :: \
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" );
+
+#endif /* ARMv3 */
+
+#if defined(__alpha__)
+
+#define MULADDC_INIT \
+ asm( "ldq $1, %0 " :: "m" (s)); \
+ asm( "ldq $2, %0 " :: "m" (d)); \
+ asm( "ldq $3, %0 " :: "m" (c)); \
+ asm( "ldq $4, %0 " :: "m" (b));
+
+#define MULADDC_CORE \
+ asm( "ldq $6, 0($1) " ); \
+ asm( "addq $1, 8, $1 " ); \
+ asm( "mulq $6, $4, $7 " ); \
+ asm( "umulh $6, $4, $6 " ); \
+ asm( "addq $7, $3, $7 " ); \
+ asm( "cmpult $7, $3, $3 " ); \
+ asm( "ldq $5, 0($2) " ); \
+ asm( "addq $7, $5, $7 " ); \
+ asm( "cmpult $7, $5, $5 " ); \
+ asm( "stq $7, 0($2) " ); \
+ asm( "addq $2, 8, $2 " ); \
+ asm( "addq $6, $3, $3 " ); \
+ asm( "addq $5, $3, $3 " );
+
+#define MULADDC_STOP \
+ asm( "stq $3, %0 " : "=m" (c)); \
+ asm( "stq $2, %0 " : "=m" (d)); \
+ asm( "stq $1, %0 " : "=m" (s) :: \
+ "$1", "$2", "$3", "$4", "$5", "$6", "$7" );
+
+#endif /* Alpha */
+
+#if defined(__mips__)
+
+#define MULADDC_INIT \
+ asm( "lw $10, %0 " :: "m" (s)); \
+ asm( "lw $11, %0 " :: "m" (d)); \
+ asm( "lw $12, %0 " :: "m" (c)); \
+ asm( "lw $13, %0 " :: "m" (b));
+
+#define MULADDC_CORE \
+ asm( "lw $14, 0($10) " ); \
+ asm( "multu $13, $14 " ); \
+ asm( "addi $10, $10, 4 " ); \
+ asm( "mflo $14 " ); \
+ asm( "mfhi $9 " ); \
+ asm( "addu $14, $12, $14 " ); \
+ asm( "lw $15, 0($11) " ); \
+ asm( "sltu $12, $14, $12 " ); \
+ asm( "addu $15, $14, $15 " ); \
+ asm( "sltu $14, $15, $14 " ); \
+ asm( "addu $12, $12, $9 " ); \
+ asm( "sw $15, 0($11) " ); \
+ asm( "addu $12, $12, $14 " ); \
+ asm( "addi $11, $11, 4 " );
+
+#define MULADDC_STOP \
+ asm( "sw $12, %0 " : "=m" (c)); \
+ asm( "sw $11, %0 " : "=m" (d)); \
+ asm( "sw $10, %0 " : "=m" (s) :: \
+ "$9", "$10", "$11", "$12", "$13", "$14", "$15" );
+
+#endif /* MIPS */
+#endif /* GNUC */
+
+#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
+
+#define MULADDC_INIT \
+ __asm mov esi, s \
+ __asm mov edi, d \
+ __asm mov ecx, c \
+ __asm mov ebx, b
+
+#define MULADDC_CORE \
+ __asm lodsd \
+ __asm mul ebx \
+ __asm add eax, ecx \
+ __asm adc edx, 0 \
+ __asm add eax, [edi] \
+ __asm adc edx, 0 \
+ __asm mov ecx, edx \
+ __asm stosd
+
+#if defined(POLARSSL_HAVE_SSE2)
+
+#define EMIT __asm _emit
+
+#define MULADDC_HUIT \
+ EMIT 0x0F EMIT 0x6E EMIT 0xC9 \
+ EMIT 0x0F EMIT 0x6E EMIT 0xC3 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x1F \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
+ EMIT 0x0F EMIT 0x6E EMIT 0x16 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
+ EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xDC \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xEE \
+ EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xFC \
+ EMIT 0x0F EMIT 0x7E EMIT 0x0F \
+ EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
+ EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCD \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCF \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCC \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xDD \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCE \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \
+ EMIT 0x83 EMIT 0xC7 EMIT 0x20 \
+ EMIT 0x83 EMIT 0xC6 EMIT 0x20 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0x7E EMIT 0xC9
+
+#define MULADDC_STOP \
+ EMIT 0x0F EMIT 0x77 \
+ __asm mov c, ecx \
+ __asm mov d, edi \
+ __asm mov s, esi \
+
+#else
+
+#define MULADDC_STOP \
+ __asm mov c, ecx \
+ __asm mov d, edi \
+ __asm mov s, esi \
+
+#endif /* SSE2 */
+#endif /* MSVC */
+
+#endif /* POLARSSL_HAVE_ASM */
+
+#if !defined(MULADDC_CORE)
+#if defined(POLARSSL_HAVE_LONGLONG)
+
+#define MULADDC_INIT \
+{ \
+ t_dbl r; \
+ t_int r0, r1;
+
+#define MULADDC_CORE \
+ r = *(s++) * (t_dbl) b; \
+ r0 = r; \
+ r1 = r >> biL; \
+ r0 += c; r1 += (r0 < c); \
+ r0 += *d; r1 += (r0 < *d); \
+ c = r1; *(d++) = r0;
+
+#define MULADDC_STOP \
+}
+
+#else
+#define MULADDC_INIT \
+{ \
+ t_int s0, s1, b0, b1; \
+ t_int r0, r1, rx, ry; \
+ b0 = ( b << biH ) >> biH; \
+ b1 = ( b >> biH );
+
+#define MULADDC_CORE \
+ s0 = ( *s << biH ) >> biH; \
+ s1 = ( *s >> biH ); s++; \
+ rx = s0 * b1; r0 = s0 * b0; \
+ ry = s1 * b0; r1 = s1 * b1; \
+ r1 += ( rx >> biH ); \
+ r1 += ( ry >> biH ); \
+ rx <<= biH; ry <<= biH; \
+ r0 += rx; r1 += (r0 < rx); \
+ r0 += ry; r1 += (r0 < ry); \
+ r0 += c; r1 += (r0 < c); \
+ r0 += *d; r1 += (r0 < *d); \
+ c = r1; *(d++) = r0;
+
+#define MULADDC_STOP \
+}
+
+#endif /* C (generic) */
+#endif /* C (longlong) */
+
+#endif /* bn_mul.h */
diff --git a/libs/luci-lib-px5g/src/polarssl/config.h b/libs/luci-lib-px5g/src/polarssl/config.h
new file mode 100644
index 0000000000..6463e5219f
--- /dev/null
+++ b/libs/luci-lib-px5g/src/polarssl/config.h
@@ -0,0 +1,329 @@
+/**
+ * \file config.h
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * 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 names of PolarSSL or XySSL 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.
+ *
+ * This set of compile-time options may be used to enable
+ * or disable features selectively, and reduce the global
+ * memory footprint.
+ */
+#ifndef POLARSSL_CONFIG_H
+#define POLARSSL_CONFIG_H
+
+#ifndef _CRT_SECURE_NO_DEPRECATE
+#define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+
+/*
+ * Uncomment if native integers are 8-bit wide.
+ *
+#define POLARSSL_HAVE_INT8
+ */
+
+/*
+ * Uncomment if native integers are 16-bit wide.
+ *
+#define POLARSSL_HAVE_INT16
+ */
+
+/*
+ * Uncomment if the compiler supports long long.
+ */
+#define POLARSSL_HAVE_LONGLONG
+
+
+/*
+ * Uncomment to enable the use of assembly code.
+ */
+#define POLARSSL_HAVE_ASM
+
+/*
+ * Uncomment if the CPU supports SSE2 (IA-32 specific).
+ *
+#define POLARSSL_HAVE_SSE2
+ */
+
+/*
+ * Enable all SSL/TLS debugging messages.
+ */
+#define POLARSSL_DEBUG_MSG
+
+/*
+ * Enable the checkup functions (*_self_test).
+ */
+#define POLARSSL_SELF_TEST
+
+/*
+ * Enable the prime-number generation code.
+ */
+#define POLARSSL_GENPRIME
+
+/*
+ * Uncomment this macro to store the AES tables in ROM.
+ *
+#define POLARSSL_AES_ROM_TABLES
+ */
+
+/*
+ * Module: library/aes.c
+ * Caller: library/ssl_tls.c
+ *
+ * This module enables the following ciphersuites:
+ * SSL_RSA_AES_128_SHA
+ * SSL_RSA_AES_256_SHA
+ * SSL_EDH_RSA_AES_256_SHA
+ */
+#define POLARSSL_AES_C
+
+/*
+ * Module: library/arc4.c
+ * Caller: library/ssl_tls.c
+ *
+ * This module enables the following ciphersuites:
+ * SSL_RSA_RC4_128_MD5
+ * SSL_RSA_RC4_128_SHA
+ */
+#define POLARSSL_ARC4_C
+
+/*
+ * Module: library/base64.c
+ * Caller: library/x509parse.c
+ *
+ * This module is required for X.509 support.
+ */
+#define POLARSSL_BASE64_C
+
+/*
+ * Module: library/bignum.c
+ * Caller: library/dhm.c
+ * library/rsa.c
+ * library/ssl_tls.c
+ * library/x509parse.c
+ *
+ * This module is required for RSA and DHM support.
+ */
+#define POLARSSL_BIGNUM_C
+
+/*
+ * Module: library/camellia.c
+ * Caller:
+ *
+ * This module enabled the following cipher suites:
+ */
+#define POLARSSL_CAMELLIA_C
+
+/*
+ * Module: library/certs.c
+ * Caller:
+ *
+ * This module is used for testing (ssl_client/server).
+ */
+#define POLARSSL_CERTS_C
+
+/*
+ * Module: library/debug.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ *
+ * This module provides debugging functions.
+ */
+#define POLARSSL_DEBUG_C
+
+/*
+ * Module: library/des.c
+ * Caller: library/ssl_tls.c
+ *
+ * This module enables the following ciphersuites:
+ * SSL_RSA_DES_168_SHA
+ * SSL_EDH_RSA_DES_168_SHA
+ */
+#define POLARSSL_DES_C
+
+/*
+ * Module: library/dhm.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * This module enables the following ciphersuites:
+ * SSL_EDH_RSA_DES_168_SHA
+ * SSL_EDH_RSA_AES_256_SHA
+ */
+#define POLARSSL_DHM_C
+
+/*
+ * Module: library/havege.c
+ * Caller:
+ *
+ * This module enables the HAVEGE random number generator.
+ */
+#define POLARSSL_HAVEGE_C
+
+/*
+ * Module: library/md2.c
+ * Caller: library/x509parse.c
+ *
+ * Uncomment to enable support for (rare) MD2-signed X.509 certs.
+ *
+#define POLARSSL_MD2_C
+ */
+
+/*
+ * Module: library/md4.c
+ * Caller: library/x509parse.c
+ *
+ * Uncomment to enable support for (rare) MD4-signed X.509 certs.
+ *
+#define POLARSSL_MD4_C
+ */
+
+/*
+ * Module: library/md5.c
+ * Caller: library/ssl_tls.c
+ * library/x509parse.c
+ *
+ * This module is required for SSL/TLS and X.509.
+ */
+#define POLARSSL_MD5_C
+
+/*
+ * Module: library/net.c
+ * Caller:
+ *
+ * This module provides TCP/IP networking routines.
+ */
+#define POLARSSL_NET_C
+
+/*
+ * Module: library/padlock.c
+ * Caller: library/aes.c
+ *
+ * This modules adds support for the VIA PadLock on x86.
+ */
+#define POLARSSL_PADLOCK_C
+
+/*
+ * Module: library/rsa.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ * library/x509.c
+ *
+ * This module is required for SSL/TLS and MD5-signed certificates.
+ */
+#define POLARSSL_RSA_C
+
+/*
+ * Module: library/sha1.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ * library/x509parse.c
+ *
+ * This module is required for SSL/TLS and SHA1-signed certificates.
+ */
+#define POLARSSL_SHA1_C
+
+/*
+ * Module: library/sha2.c
+ * Caller:
+ *
+ * This module adds support for SHA-224 and SHA-256.
+ */
+#define POLARSSL_SHA2_C
+
+/*
+ * Module: library/sha4.c
+ * Caller:
+ *
+ * This module adds support for SHA-384 and SHA-512.
+ */
+#define POLARSSL_SHA4_C
+
+/*
+ * Module: library/ssl_cli.c
+ * Caller:
+ *
+ * This module is required for SSL/TLS client support.
+ */
+#define POLARSSL_SSL_CLI_C
+
+/*
+ * Module: library/ssl_srv.c
+ * Caller:
+ *
+ * This module is required for SSL/TLS server support.
+ */
+#define POLARSSL_SSL_SRV_C
+
+/*
+ * Module: library/ssl_tls.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * This module is required for SSL/TLS.
+ */
+#define POLARSSL_SSL_TLS_C
+
+/*
+ * Module: library/timing.c
+ * Caller: library/havege.c
+ *
+ * This module is used by the HAVEGE random number generator.
+ */
+#define POLARSSL_TIMING_C
+
+/*
+ * Module: library/x509parse.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ *
+ * This module is required for X.509 certificate parsing.
+ */
+#define POLARSSL_X509_PARSE_C
+
+/*
+ * Module: library/x509_write.c
+ * Caller:
+ *
+ * This module is required for X.509 certificate writing.
+ */
+#define POLARSSL_X509_WRITE_C
+
+/*
+ * Module: library/xtea.c
+ * Caller:
+ */
+#define POLARSSL_XTEA_C
+
+#endif /* config.h */
diff --git a/libs/luci-lib-px5g/src/polarssl/havege.h b/libs/luci-lib-px5g/src/polarssl/havege.h
new file mode 100644
index 0000000000..c27cecac0f
--- /dev/null
+++ b/libs/luci-lib-px5g/src/polarssl/havege.h
@@ -0,0 +1,75 @@
+/**
+ * \file havege.h
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * 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 names of PolarSSL or XySSL 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 POLARSSL_HAVEGE_H
+#define POLARSSL_HAVEGE_H
+
+#define COLLECT_SIZE 1024
+
+/**
+ * \brief HAVEGE state structure
+ */
+typedef struct
+{
+ int PT1, PT2, offset[2];
+ int pool[COLLECT_SIZE];
+ int WALK[8192];
+}
+havege_state;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief HAVEGE initialization
+ *
+ * \param hs HAVEGE state to be initialized
+ */
+void havege_init( havege_state *hs );
+
+/**
+ * \brief HAVEGE rand function
+ *
+ * \param rng_st points to an HAVEGE state
+ *
+ * \return A random int
+ */
+int havege_rand( void *p_rng );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* havege.h */
diff --git a/libs/luci-lib-px5g/src/polarssl/rsa.h b/libs/luci-lib-px5g/src/polarssl/rsa.h
new file mode 100644
index 0000000000..b31dc2f144
--- /dev/null
+++ b/libs/luci-lib-px5g/src/polarssl/rsa.h
@@ -0,0 +1,309 @@
+/**
+ * \file rsa.h
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * 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 names of PolarSSL or XySSL 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 POLARSSL_RSA_H
+#define POLARSSL_RSA_H
+
+#include "polarssl/bignum.h"
+
+#define POLARSSL_ERR_RSA_BAD_INPUT_DATA -0x0400
+#define POLARSSL_ERR_RSA_INVALID_PADDING -0x0410
+#define POLARSSL_ERR_RSA_KEY_GEN_FAILED -0x0420
+#define POLARSSL_ERR_RSA_KEY_CHECK_FAILED -0x0430
+#define POLARSSL_ERR_RSA_PUBLIC_FAILED -0x0440
+#define POLARSSL_ERR_RSA_PRIVATE_FAILED -0x0450
+#define POLARSSL_ERR_RSA_VERIFY_FAILED -0x0460
+#define POLARSSL_ERR_RSA_OUTPUT_TO_LARGE -0x0470
+
+/*
+ * PKCS#1 constants
+ */
+#define RSA_RAW 0
+#define RSA_MD2 2
+#define RSA_MD4 3
+#define RSA_MD5 4
+#define RSA_SHA1 5
+#define RSA_SHA256 6
+
+#define RSA_PUBLIC 0
+#define RSA_PRIVATE 1
+
+#define RSA_PKCS_V15 0
+#define RSA_PKCS_V21 1
+
+#define RSA_SIGN 1
+#define RSA_CRYPT 2
+
+/*
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm DigestAlgorithmIdentifier,
+ * digest Digest }
+ *
+ * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+ *
+ * Digest ::= OCTET STRING
+ */
+#define ASN1_HASH_MDX \
+ "\x30\x20\x30\x0C\x06\x08\x2A\x86\x48" \
+ "\x86\xF7\x0D\x02\x00\x05\x00\x04\x10"
+
+#define ASN1_HASH_SHA1 \
+ "\x30\x21\x30\x09\x06\x05\x2B\x0E\x03" \
+ "\x02\x1A\x05\x00\x04\x14"
+
+/**
+ * \brief RSA context structure
+ */
+typedef struct
+{
+ int ver; /*!< always 0 */
+ int len; /*!< size(N) in chars */
+
+ mpi N; /*!< public modulus */
+ mpi E; /*!< public exponent */
+
+ mpi D; /*!< private exponent */
+ mpi P; /*!< 1st prime factor */
+ mpi Q; /*!< 2nd prime factor */
+ mpi DP; /*!< D % (P - 1) */
+ mpi DQ; /*!< D % (Q - 1) */
+ mpi QP; /*!< 1 / (Q % P) */
+
+ mpi RN; /*!< cached R^2 mod N */
+ mpi RP; /*!< cached R^2 mod P */
+ mpi RQ; /*!< cached R^2 mod Q */
+
+ int padding; /*!< 1.5 or OAEP/PSS */
+ int hash_id; /*!< hash identifier */
+ int (*f_rng)(void *); /*!< RNG function */
+ void *p_rng; /*!< RNG parameter */
+}
+rsa_context;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Initialize an RSA context
+ *
+ * \param ctx RSA context to be initialized
+ * \param padding RSA_PKCS_V15 or RSA_PKCS_V21
+ * \param hash_id RSA_PKCS_V21 hash identifier
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
+ *
+ * \note The hash_id parameter is actually ignored
+ * when using RSA_PKCS_V15 padding.
+ *
+ * \note Currently (xyssl-0.8), RSA_PKCS_V21 padding
+ * is not supported.
+ */
+void rsa_init( rsa_context *ctx,
+ int padding,
+ int hash_id,
+ int (*f_rng)(void *),
+ void *p_rng );
+
+/**
+ * \brief Generate an RSA keypair
+ *
+ * \param ctx RSA context that will hold the key
+ * \param nbits size of the public key in bits
+ * \param exponent public exponent (e.g., 65537)
+ *
+ * \note rsa_init() must be called beforehand to setup
+ * the RSA context (especially f_rng and p_rng).
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ */
+int rsa_gen_key( rsa_context *ctx, int nbits, int exponent );
+
+/**
+ * \brief Check a public RSA key
+ *
+ * \param ctx RSA context to be checked
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ */
+int rsa_check_pubkey( rsa_context *ctx );
+
+/**
+ * \brief Check a private RSA key
+ *
+ * \param ctx RSA context to be checked
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ */
+int rsa_check_privkey( rsa_context *ctx );
+
+/**
+ * \brief Do an RSA public key operation
+ *
+ * \param ctx RSA context
+ * \param input input buffer
+ * \param output output buffer
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note This function does NOT take care of message
+ * padding. Also, be sure to set input[0] = 0.
+ *
+ * \note The input and output buffers must be large
+ * enough (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_public( rsa_context *ctx,
+ unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief Do an RSA private key operation
+ *
+ * \param ctx RSA context
+ * \param input input buffer
+ * \param output output buffer
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The input and output buffers must be large
+ * enough (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_private( rsa_context *ctx,
+ unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief Add the message padding, then do an RSA operation
+ *
+ * \param ctx RSA context
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param ilen contains the the plaintext length
+ * \param input buffer holding the data to be encrypted
+ * \param output buffer that will hold the ciphertext
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The output buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_pkcs1_encrypt( rsa_context *ctx,
+ int mode, int ilen,
+ unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief Do an RSA operation, then remove the message padding
+ *
+ * \param ctx RSA context
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param input buffer holding the encrypted data
+ * \param output buffer that will hold the plaintext
+ * \param olen will contain the plaintext length
+ * \param output_max_len maximum length of the output buffer
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The output buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
+ * an error is thrown.
+ */
+int rsa_pkcs1_decrypt( rsa_context *ctx,
+ int mode, int *olen,
+ unsigned char *input,
+ unsigned char *output,
+ int output_max_len);
+
+/**
+ * \brief Do a private RSA to sign a message digest
+ *
+ * \param ctx RSA context
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param hash_id RSA_RAW, RSA_MD{2,4,5} or RSA_SHA{1,256}
+ * \param hashlen message digest length (for RSA_RAW only)
+ * \param hash buffer holding the message digest
+ * \param sig buffer that will hold the ciphertext
+ *
+ * \return 0 if the signing operation was successful,
+ * or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The "sig" buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_pkcs1_sign( rsa_context *ctx,
+ int mode,
+ int hash_id,
+ int hashlen,
+ unsigned char *hash,
+ unsigned char *sig );
+
+/**
+ * \brief Do a public RSA and check the message digest
+ *
+ * \param ctx points to an RSA public key
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param hash_id RSA_RAW, RSA_MD{2,4,5} or RSA_SHA{1,256}
+ * \param hashlen message digest length (for RSA_RAW only)
+ * \param hash buffer holding the message digest
+ * \param sig buffer holding the ciphertext
+ *
+ * \return 0 if the verify operation was successful,
+ * or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The "sig" buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_pkcs1_verify( rsa_context *ctx,
+ int mode,
+ int hash_id,
+ int hashlen,
+ unsigned char *hash,
+ unsigned char *sig );
+
+/**
+ * \brief Free the components of an RSA key
+ */
+void rsa_free( rsa_context *ctx );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int rsa_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* rsa.h */
diff --git a/libs/luci-lib-px5g/src/polarssl/sha1.h b/libs/luci-lib-px5g/src/polarssl/sha1.h
new file mode 100644
index 0000000000..3ca7dc3195
--- /dev/null
+++ b/libs/luci-lib-px5g/src/polarssl/sha1.h
@@ -0,0 +1,150 @@
+/**
+ * \file sha1.h
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * 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 names of PolarSSL or XySSL 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 POLARSSL_SHA1_H
+#define POLARSSL_SHA1_H
+
+/**
+ * \brief SHA-1 context structure
+ */
+typedef struct
+{
+ unsigned long total[2]; /*!< number of bytes processed */
+ unsigned long state[5]; /*!< intermediate digest state */
+ unsigned char buffer[64]; /*!< data block being processed */
+
+ unsigned char ipad[64]; /*!< HMAC: inner padding */
+ unsigned char opad[64]; /*!< HMAC: outer padding */
+}
+sha1_context;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief SHA-1 context setup
+ *
+ * \param ctx context to be initialized
+ */
+void sha1_starts( sha1_context *ctx );
+
+/**
+ * \brief SHA-1 process buffer
+ *
+ * \param ctx SHA-1 context
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ */
+void sha1_update( sha1_context *ctx, unsigned char *input, int ilen );
+
+/**
+ * \brief SHA-1 final digest
+ *
+ * \param ctx SHA-1 context
+ * \param output SHA-1 checksum result
+ */
+void sha1_finish( sha1_context *ctx, unsigned char output[20] );
+
+/**
+ * \brief Output = SHA-1( input buffer )
+ *
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ * \param output SHA-1 checksum result
+ */
+void sha1( unsigned char *input, int ilen, unsigned char output[20] );
+
+/**
+ * \brief Output = SHA-1( file contents )
+ *
+ * \param path input file name
+ * \param output SHA-1 checksum result
+ *
+ * \return 0 if successful, 1 if fopen failed,
+ * or 2 if fread failed
+ */
+int sha1_file( char *path, unsigned char output[20] );
+
+/**
+ * \brief SHA-1 HMAC context setup
+ *
+ * \param ctx HMAC context to be initialized
+ * \param key HMAC secret key
+ * \param keylen length of the HMAC key
+ */
+void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen );
+
+/**
+ * \brief SHA-1 HMAC process buffer
+ *
+ * \param ctx HMAC context
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ */
+void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen );
+
+/**
+ * \brief SHA-1 HMAC final digest
+ *
+ * \param ctx HMAC context
+ * \param output SHA-1 HMAC checksum result
+ */
+void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] );
+
+/**
+ * \brief Output = HMAC-SHA-1( hmac key, input buffer )
+ *
+ * \param key HMAC secret key
+ * \param keylen length of the HMAC key
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ * \param output HMAC-SHA-1 result
+ */
+void sha1_hmac( unsigned char *key, int keylen,
+ unsigned char *input, int ilen,
+ unsigned char output[20] );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int sha1_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* sha1.h */
diff --git a/libs/luci-lib-px5g/src/polarssl/timing.h b/libs/luci-lib-px5g/src/polarssl/timing.h
new file mode 100644
index 0000000000..62d627f61b
--- /dev/null
+++ b/libs/luci-lib-px5g/src/polarssl/timing.h
@@ -0,0 +1,81 @@
+/**
+ * \file timing.h
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * 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 names of PolarSSL or XySSL 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 POLARSSL_TIMING_H
+#define POLARSSL_TIMING_H
+
+/**
+ * \brief timer structure
+ */
+struct hr_time
+{
+ unsigned char opaque[32];
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int alarmed;
+
+/**
+ * \brief Return the CPU cycle counter value
+ */
+unsigned long hardclock( void );
+
+/**
+ * \brief Return the elapsed time in milliseconds
+ *
+ * \param val points to a timer structure
+ * \param reset if set to 1, the timer is restarted
+ */
+unsigned long get_timer( struct hr_time *val, int reset );
+
+/**
+ * \brief Setup an alarm clock
+ *
+ * \param seconds delay before the "alarmed" flag is set
+ */
+void set_alarm( int seconds );
+
+/**
+ * \brief Sleep for a certain amount of time
+ */
+void m_sleep( int milliseconds );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* timing.h */
diff --git a/libs/luci-lib-px5g/src/polarssl/x509.h b/libs/luci-lib-px5g/src/polarssl/x509.h
new file mode 100644
index 0000000000..908a1dbf51
--- /dev/null
+++ b/libs/luci-lib-px5g/src/polarssl/x509.h
@@ -0,0 +1,549 @@
+/**
+ * \file x509.h
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * 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 names of PolarSSL or XySSL 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 POLARSSL_X509_H
+#define POLARSSL_X509_H
+
+#include "polarssl/rsa.h"
+
+#define POLARSSL_ERR_ASN1_OUT_OF_DATA -0x0014
+#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG -0x0016
+#define POLARSSL_ERR_ASN1_INVALID_LENGTH -0x0018
+#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH -0x001A
+#define POLARSSL_ERR_ASN1_INVALID_DATA -0x001C
+
+#define POLARSSL_ERR_X509_FEATURE_UNAVAILABLE -0x0020
+#define POLARSSL_ERR_X509_CERT_INVALID_PEM -0x0040
+#define POLARSSL_ERR_X509_CERT_INVALID_FORMAT -0x0060
+#define POLARSSL_ERR_X509_CERT_INVALID_VERSION -0x0080
+#define POLARSSL_ERR_X509_CERT_INVALID_SERIAL -0x00A0
+#define POLARSSL_ERR_X509_CERT_INVALID_ALG -0x00C0
+#define POLARSSL_ERR_X509_CERT_INVALID_NAME -0x00E0
+#define POLARSSL_ERR_X509_CERT_INVALID_DATE -0x0100
+#define POLARSSL_ERR_X509_CERT_INVALID_PUBKEY -0x0120
+#define POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE -0x0140
+#define POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS -0x0160
+#define POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION -0x0180
+#define POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG -0x01A0
+#define POLARSSL_ERR_X509_CERT_UNKNOWN_PK_ALG -0x01C0
+#define POLARSSL_ERR_X509_CERT_SIG_MISMATCH -0x01E0
+#define POLARSSL_ERR_X509_CERT_VERIFY_FAILED -0x0200
+#define POLARSSL_ERR_X509_KEY_INVALID_PEM -0x0220
+#define POLARSSL_ERR_X509_KEY_INVALID_VERSION -0x0240
+#define POLARSSL_ERR_X509_KEY_INVALID_FORMAT -0x0260
+#define POLARSSL_ERR_X509_KEY_INVALID_ENC_IV -0x0280
+#define POLARSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG -0x02A0
+#define POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED -0x02C0
+#define POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH -0x02E0
+#define POLARSSL_ERR_X509_POINT_ERROR -0x0300
+#define POLARSSL_ERR_X509_VALUE_TO_LENGTH -0x0320
+
+#define BADCERT_EXPIRED 1
+#define BADCERT_REVOKED 2
+#define BADCERT_CN_MISMATCH 4
+#define BADCERT_NOT_TRUSTED 8
+
+/*
+ * DER constants
+ */
+#define ASN1_BOOLEAN 0x01
+#define ASN1_INTEGER 0x02
+#define ASN1_BIT_STRING 0x03
+#define ASN1_OCTET_STRING 0x04
+#define ASN1_NULL 0x05
+#define ASN1_OID 0x06
+#define ASN1_UTF8_STRING 0x0C
+#define ASN1_SEQUENCE 0x10
+#define ASN1_SET 0x11
+#define ASN1_PRINTABLE_STRING 0x13
+#define ASN1_T61_STRING 0x14
+#define ASN1_IA5_STRING 0x16
+#define ASN1_UTC_TIME 0x17
+#define ASN1_UNIVERSAL_STRING 0x1C
+#define ASN1_BMP_STRING 0x1E
+#define ASN1_PRIMITIVE 0x00
+#define ASN1_CONSTRUCTED 0x20
+#define ASN1_CONTEXT_SPECIFIC 0x80
+
+/*
+ * various object identifiers
+ */
+#define X520_COMMON_NAME 3
+#define X520_COUNTRY 6
+#define X520_LOCALITY 7
+#define X520_STATE 8
+#define X520_ORGANIZATION 10
+#define X520_ORG_UNIT 11
+#define PKCS9_EMAIL 1
+
+#define X509_OUTPUT_DER 0x01
+#define X509_OUTPUT_PEM 0x02
+#define PEM_LINE_LENGTH 72
+#define X509_ISSUER 0x01
+#define X509_SUBJECT 0x02
+
+#define OID_X520 "\x55\x04"
+#define OID_CN "\x55\x04\x03"
+#define OID_PKCS1 "\x2A\x86\x48\x86\xF7\x0D\x01\x01"
+#define OID_PKCS1_RSA "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01"
+#define OID_PKCS1_RSA_SHA "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05"
+#define OID_PKCS9 "\x2A\x86\x48\x86\xF7\x0D\x01\x09"
+#define OID_PKCS9_EMAIL "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01"
+
+/*
+ * Structures for parsing X.509 certificates
+ */
+typedef struct _x509_buf
+{
+ int tag;
+ int len;
+ unsigned char *p;
+}
+x509_buf;
+
+typedef struct _x509_name
+{
+ x509_buf oid;
+ x509_buf val;
+ struct _x509_name *next;
+}
+x509_name;
+
+typedef struct _x509_time
+{
+ int year, mon, day;
+ int hour, min, sec;
+}
+x509_time;
+
+typedef struct _x509_cert
+{
+ x509_buf raw;
+ x509_buf tbs;
+
+ int version;
+ x509_buf serial;
+ x509_buf sig_oid1;
+
+ x509_buf issuer_raw;
+ x509_buf subject_raw;
+
+ x509_name issuer;
+ x509_name subject;
+
+ x509_time valid_from;
+ x509_time valid_to;
+
+ x509_buf pk_oid;
+ rsa_context rsa;
+
+ x509_buf issuer_id;
+ x509_buf subject_id;
+ x509_buf v3_ext;
+
+ int ca_istrue;
+ int max_pathlen;
+
+ x509_buf sig_oid2;
+ x509_buf sig;
+
+ struct _x509_cert *next;
+}
+x509_cert;
+
+/*
+ * Structures for writing X.509 certificates
+ */
+typedef struct _x509_node
+{
+ unsigned char *data;
+ unsigned char *p;
+ unsigned char *end;
+
+ size_t len;
+}
+x509_node;
+
+typedef struct _x509_raw
+{
+ x509_node raw;
+ x509_node tbs;
+
+ x509_node version;
+ x509_node serial;
+ x509_node tbs_signalg;
+ x509_node issuer;
+ x509_node validity;
+ x509_node subject;
+ x509_node subpubkey;
+
+ x509_node signalg;
+ x509_node sign;
+}
+x509_raw;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Parse one or more certificates and add them
+ * to the chained list
+ *
+ * \param chain points to the start of the chain
+ * \param buf buffer holding the certificate data
+ * \param buflen size of the buffer
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509parse_crt( x509_cert *crt, unsigned char *buf, int buflen );
+
+/**
+ * \brief Load one or more certificates and add them
+ * to the chained list
+ *
+ * \param chain points to the start of the chain
+ * \param path filename to read the certificates from
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509parse_crtfile( x509_cert *crt, char *path );
+
+/**
+ * \brief Parse a private RSA key
+ *
+ * \param rsa RSA context to be initialized
+ * \param buf input buffer
+ * \param buflen size of the buffer
+ * \param pwd password for decryption (optional)
+ * \param pwdlen size of the password
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509parse_key( rsa_context *rsa,
+ unsigned char *buf, int buflen,
+ unsigned char *pwd, int pwdlen );
+
+/**
+ * \brief Load and parse a private RSA key
+ *
+ * \param rsa RSA context to be initialized
+ * \param path filename to read the private key from
+ * \param pwd password to decrypt the file (can be NULL)
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509parse_keyfile( rsa_context *rsa, char *path, char *password );
+
+/**
+ * \brief Store the certificate DN in printable form into buf;
+ * no more than (end - buf) characters will be written.
+ */
+int x509parse_dn_gets( char *buf, char *end, x509_name *dn );
+
+/**
+ * \brief Returns an informational string about the
+ * certificate.
+ */
+char *x509parse_cert_info( char *prefix, x509_cert *crt );
+
+/**
+ * \brief Return 0 if the certificate is still valid,
+ * or BADCERT_EXPIRED
+ */
+int x509parse_expired( x509_cert *crt );
+
+/**
+ * \brief Verify the certificate signature
+ *
+ * \param crt a certificate to be verified
+ * \param trust_ca the trusted CA chain
+ * \param cn expected Common Name (can be set to
+ * NULL if the CN must not be verified)
+ * \param flags result of the verification
+ *
+ * \return 0 if successful or POLARSSL_ERR_X509_SIG_VERIFY_FAILED,
+ * in which case *flags will have one or more of
+ * the following values set:
+ * BADCERT_EXPIRED --
+ * BADCERT_REVOKED --
+ * BADCERT_CN_MISMATCH --
+ * BADCERT_NOT_TRUSTED
+ *
+ * \note TODO: add two arguments, depth and crl
+ */
+int x509parse_verify( x509_cert *crt,
+ x509_cert *trust_ca,
+ char *cn, int *flags );
+
+/**
+ * \brief Unallocate all certificate data
+ */
+void x509_free( x509_cert *crt );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int x509_self_test( int verbose );
+
+/**
+ * \brief Write a certificate info file
+ *
+ * \param chain points to the raw certificate data
+ * \param path filename to write the certificate to
+ * \param format X509_OUTPUT_DER or X509_OUTPUT_PEM
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_crtfile( x509_raw *chain,
+ unsigned char *path,
+ int format );
+
+/**
+ * \brief Write a certificate signing request message format file
+ *
+ * \param chain points to the raw certificate (with x509write_create_csr) data
+ * \param path filename to write the certificate to
+ * \param format X509_OUTPUT_DER or X509_OUTPUT_PEM
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_csrfile( x509_raw *chain,
+ unsigned char *path,
+ int format );
+
+/*
+ * \brief Write a private RSA key into a file
+ *
+ * \param rsa points to an RSA key
+ * \param path filename to write the key to
+ * \param format X509_OUTPUT_DER or X509_OUTPUT_PEM
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_keyfile( rsa_context *rsa,
+ char *path,
+ int format );
+
+/**
+ * \brief Add a public key to certificate
+ *
+ * \param chain points to the raw certificate data
+ * \param pubkey points to an RSA key
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_add_pubkey( x509_raw *chain, rsa_context *pubkey );
+
+/**
+ * \brief Create x509 subject/issuer field to raw certificate
+ * from string or CA cert. Make string NULL if you will
+ * use the CA copy function or make CA NULL then used
+ * the string parse.
+ *
+ * \param chain points to the raw certificate data
+ * \param names a string that can hold (separete with ";"):
+ * CN=CommonName
+ * -- O=Organization
+ * -- OU=OrgUnit
+ * -- ST=State
+ * -- L=Locality
+ * -- R=Email
+ * -- C=Country
+ * . Make that NULL if you didn't need that.
+ * \param flag flag is X509_ISSUER or X509_SUBJECT that defined
+ * where change
+ * \param ca the certificate for copy data. Make that NULL if you
+ * didn't need that.
+ * \param ca_flag set the ca field from copy to crt
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_add_customize ( x509_raw *crt,
+ unsigned char *names,
+ int flag,
+ x509_cert *ca,
+ int ca_flag );
+
+/**
+* \brief Add x509 issuer field
+*
+* \param chain points to the raw certificate data
+* \param issuer a string holding (separete with ";"):
+* CN=CommonName
+* -- O=Organization
+* -- OU=OrgUnit
+* -- ST=State
+* -- L=Locality
+* -- R=Email
+* -- C=Country
+* . Set this to NULL if not needed.
+* \return 0 if successful, or a specific X509 error code
+*/
+int x509write_add_issuer( x509_raw *crt, unsigned char *issuer);
+
+/**
+ * \brief Add x509 subject field
+ *
+ * \param chain points to the raw certificate data
+ * \param subject a string holding (separete with ";"):
+ * CN=CommonName
+ * -- O=Organization
+ * -- OU=OrgUnit
+ * -- ST=State
+ * -- L=Locality
+ * -- R=Email
+ * -- C=Country
+ * . Set this to NULL if not needed.
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_add_subject( x509_raw *crt, unsigned char *subject);
+
+/**
+* \brief Copy x509 issuer field from another certificate
+*
+* \param chain points to the raw certificate data
+* \param from_crt the certificate whose issuer is to be copied.
+* \return 0 if successful, or a specific X509 error code
+*/
+int x509write_copy_issuer(x509_raw *crt, x509_cert *from_crt);
+
+/**
+* \brief Copy x509 subject field from another certificate
+*
+* \param chain points to the raw certificate data
+* \param from_crt the certificate whose subject is to be copied.
+* \return 0 if successful, or a specific X509 error code
+*/
+int x509write_copy_subject(x509_raw *crt, x509_cert *from_crt);
+
+/**
+* \brief Copy x509 issuer field from the subject of another certificate
+*
+* \param chain points to the raw certificate data
+* \param from_crt the certificate whose subject is to be copied.
+* \return 0 if successful, or a specific X509 error code
+*/
+int x509write_copy_issuer_from_subject(x509_raw *crt, x509_cert *from_crt);
+
+/**
+* \brief Copy x509 subject field from the issuer of another certificate
+*
+* \param chain points to the raw certificate data
+* \param from_crt the certificate whose issuer is to be copied.
+* \return 0 if successful, or a specific X509 error code
+*/
+int x509write_copy_subject_from_issuer(x509_raw *crt, x509_cert *from_crt);
+
+/**
+ * \brief Create x509 validity time in UTC
+ *
+ * \param chain points to the raw certificate data
+ * \param before valid not before in format YYYY-MM-DD hh:mm:ss
+ * \param after valid not after in format YYYY-MM-DD hh:mm:ss
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_add_validity( x509_raw *crt,
+ unsigned char *before,
+ unsigned char *after );
+
+/**
+ * \brief Create a self-signed certificate
+ *
+ * \param chain points to the raw certificate data
+ * \param rsa a private key to sign the certificate
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_create_selfsign( x509_raw *crt, rsa_context *raw );
+
+/**
+ * \brief Create a certificate
+ *
+ * \param chain points to the raw certificate data
+ * \param rsa a private key to sign the certificate
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_create_sign( x509_raw *crt, rsa_context *raw );
+
+/**
+ * \brief Create a certificate signing request
+ *
+ * \param chain points to the raw certificate data. Didn't use the
+ * same chain that u have use for certificate.
+ * \param privkey a rsa private key
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_create_csr( x509_raw *chain, rsa_context *privkey );
+
+/**
+ * \brief Serialize an rsa key into DER
+ *
+ * \param rsa a rsa key for output
+ * \param node a x509 node for write into
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_serialize_key( rsa_context *rsa, x509_node *node );
+
+/**
+ * \brief Unallocate all raw certificate data
+ */
+void x509write_free_raw( x509_raw *crt );
+
+/**
+ * \brief Allocate all raw certificate data
+ */
+void x509write_init_raw( x509_raw *crt );
+
+/**
+ * \brief Unallocate all node certificate data
+ */
+void x509write_free_node( x509_node *crt_node );
+
+/**
+ * \brief Allocate all node certificate data
+ */
+void x509write_init_node( x509_node *crt_node );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* x509.h */