[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit
Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/app/zte_comm/zte_locknet/Makefile b/ap/app/zte_comm/zte_locknet/Makefile
new file mode 100755
index 0000000..1372932
--- /dev/null
+++ b/ap/app/zte_comm/zte_locknet/Makefile
@@ -0,0 +1,43 @@
+#*******************************************************************************
+# include ZTE application makefile
+#*******************************************************************************
+include $(COMMON_MK)
+
+##############USER COMIZE BEGIN################
+EXEC1 = zte_locknet
+
+CPU_PUB_ROOT=$(TOPDIR_AP)/../pub
+
+OBJS1 = $(patsubst %.c,%.o,$(wildcard ./src/*.c ))
+
+CFLAGS += -I.
+CFLAGS += -I./inc
+CFLAGS += -I$(zte_app_path)/include
+CFLAGS += -I$(zte_app_path)/zte_comm/at_ctl/inc
+CFLAGS += -I$(zte_lib_path)/libsqlite
+CFLAGS += -I$(LINUX_DIR)
+
+CFLAGS += -I$(CPU_PUB_ROOT)/project/zx297520v3/include/nv
+CFLAGS += -O -Dlinux=1 -DHIGH_SPEED=1
+CFLAGS += -g
+CFLAGS += -g -Werror=implicit-function-declaration
+
+LDLIBS += -lnvram_sc -L$(zte_lib_path)/libnvram
+LDLIBS += -lsoftap -L$(zte_lib_path)/libsoftap
+LDLIBS += -latutils -L$(zte_lib_path)/libatutils
+LDLIBS += -lsqlite -L$(zte_lib_path)/libsqlite
+LDLIBS += -lsoft_timer_sc -L$(zte_lib_path)/libsoft_timer
+
+LDLIBS += -lm
+LDLIBS += -lpthread -L$(zte_lib_path)/libpthread
+LDLIBS += -lcpnv -L$(zte_lib_path)/libcpnv
+##############USER COMIZE END##################
+
+#*******************************************************************************
+# targets
+#*******************************************************************************
+lib: $(OBJS1)
+ @echo Compiling zte_locknet libraries.
+
+clean:
+ -rm -f $(OBJS1)
diff --git a/ap/app/zte_comm/zte_locknet/inc/zctrm_ln_bignum.h b/ap/app/zte_comm/zte_locknet/inc/zctrm_ln_bignum.h
new file mode 100755
index 0000000..01a09c3
--- /dev/null
+++ b/ap/app/zte_comm/zte_locknet/inc/zctrm_ln_bignum.h
@@ -0,0 +1,533 @@
+/**
+ * \file bignum.h
+ *
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#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
+ #if defined(POLARSSL_HAVE_LONGLONG)
+ typedef unsigned long long t_dbl;
+ #endif
+ #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
+ *
+ * \param X MPI to grow
+ * \param nblimbs The target 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
+ *
+ * \param X Destination MPI
+ * \param Y Source MPI
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_copy( mpi *X, const mpi *Y );
+
+/**
+ * \brief Swap the contents of X and Y
+ *
+ * \param X First MPI value
+ * \param Y Second MPI value
+ */
+void mpi_swap( mpi *X, mpi *Y );
+
+/**
+ * \brief Set value from integer
+ *
+ * \param X MPI to set
+ * \param z Value to use
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_lset( mpi *X, int z );
+
+/**
+ * \brief Return the number of least significant bits
+ *
+ * \param X MPI to use
+ */
+int mpi_lsb( const mpi *X );
+
+/**
+ * \brief Return the number of most significant bits
+ *
+ * \param X MPI to use
+ */
+int mpi_msb( const mpi *X );
+
+/**
+ * \brief Return the total size in bytes
+ *
+ * \param X MPI to use
+ */
+int mpi_size( const 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, const 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.
+ * *slen is always updated to reflect the amount
+ * of data that has (or would have) been written.
+ *
+ * \note Call this function with *slen = 0 to obtain the
+ * minimum required buffer size in *slen.
+ */
+int mpi_write_string( const 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 if fout is NULL
+ *
+ * \param p Prefix, can be NULL
+ * \param X Source MPI
+ * \param radix Output numeric base
+ * \param fout Output file handle (can be NULL)
+ *
+ * \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( const char *p, const 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, const 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
+ */
+int mpi_write_binary( const mpi *X, unsigned char *buf, int buflen );
+
+/**
+ * \brief Left-shift: X <<= count
+ *
+ * \param X MPI to shift
+ * \param count Amount to shift
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_shift_l( mpi *X, int count );
+
+/**
+ * \brief Right-shift: X >>= count
+ *
+ * \param X MPI to shift
+ * \param count Amount to shift
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_shift_r( mpi *X, int count );
+
+/**
+ * \brief Compare unsigned values
+ *
+ * \param X Left-hand MPI
+ * \param Y Right-hand MPI
+ *
+ * \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( const mpi *X, const mpi *Y );
+
+/**
+ * \brief Compare signed values
+ *
+ * \param X Left-hand MPI
+ * \param Y Right-hand MPI
+ *
+ * \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( const mpi *X, const mpi *Y );
+
+/**
+ * \brief Compare signed values
+ *
+ * \param X Left-hand MPI
+ * \param z The integer value to compare to
+ *
+ * \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( const mpi *X, int z );
+
+/**
+ * \brief Unsigned addition: X = |A| + |B|
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_add_abs( mpi *X, const mpi *A, const mpi *B );
+
+/**
+ * \brief Unsigned substraction: X = |A| - |B|
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A
+ */
+int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B );
+
+/**
+ * \brief Signed addition: X = A + B
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B );
+
+/**
+ * \brief Signed substraction: X = A - B
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B );
+
+/**
+ * \brief Signed addition: X = A + b
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param b The integer value to add
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_add_int( mpi *X, const mpi *A, int b );
+
+/**
+ * \brief Signed substraction: X = A - b
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param b The integer value to subtract
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_sub_int( mpi *X, const mpi *A, int b );
+
+/**
+ * \brief Baseline multiplication: X = A * B
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B );
+
+/**
+ * \brief Baseline multiplication: X = A * b
+ * Note: b is an unsigned integer type, thus
+ * Negative values of b are ignored.
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param b The integer value to multiply with
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_mul_int( mpi *X, const mpi *A, t_int b );
+
+/**
+ * \brief Division by mpi: A = Q * B + R
+ *
+ * \param Q Destination MPI for the quotient
+ * \param R Destination MPI for the rest value
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \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, const mpi *A, const mpi *B );
+
+/**
+ * \brief Division by int: A = Q * b + R
+ *
+ * \param Q Destination MPI for the quotient
+ * \param R Destination MPI for the rest value
+ * \param A Left-hand MPI
+ * \param b Integer to divide by
+ *
+ * \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, const mpi *A, int b );
+
+/**
+ * \brief Modulo: R = A mod B
+ *
+ * \param R Destination MPI for the rest value
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0,
+ * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0
+ */
+int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B );
+
+/**
+ * \brief Modulo: r = A mod b
+ *
+ * \param r Destination t_int
+ * \param A Left-hand MPI
+ * \param b Integer to divide by
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0,
+ * POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0
+ */
+int mpi_mod_int( t_int *r, const mpi *A, int b );
+
+/**
+ * \brief Sliding-window exponentiation: X = A^E mod N
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param E Exponent MPI
+ * \param N Modular MPI
+ * \param _RR Speed-up MPI used for recalculations
+ *
+ * \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, const mpi *A, const mpi *E, const mpi *N, mpi *_RR );
+
+/**
+ * \brief Greatest common divisor: G = gcd(A, B)
+ *
+ * \param G Destination MPI
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_gcd( mpi *G, const mpi *A, const mpi *B );
+
+/**
+ * \brief Modular inverse: X = A^-1 mod N
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param N Right-hand MPI
+ *
+ * \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, const mpi *A, const mpi *N );
+
+/**
+ * \brief Miller-Rabin primality test
+ *
+ * \param X MPI to check
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
+ *
+ * \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/ap/app/zte_comm/zte_locknet/inc/zctrm_ln_bnmul.h b/ap/app/zte_comm/zte_locknet/inc/zctrm_ln_bnmul.h
new file mode 100755
index 0000000..b4a60c5
--- /dev/null
+++ b/ap/app/zte_comm/zte_locknet/inc/zctrm_ln_bnmul.h
@@ -0,0 +1,736 @@
+/**
+ * \file bn_mul.h
+ *
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+/*
+ * 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 "zctrm_ln_config.h"
+
+#if defined(POLARSSL_HAVE_ASM)
+
+#if defined(__GNUC__)
+#if defined(__i386__)
+
+#define MULADDC_INIT \
+ asm( " \
+ movl %%ebx, %0; \
+ movl %5, %%esi; \
+ movl %6, %%edi; \
+ movl %7, %%ecx; \
+ movl %8, %%ebx; \
+ "
+
+#define MULADDC_CORE \
+ " \
+ lodsl; \
+ mull %%ebx; \
+ addl %%ecx, %%eax; \
+ adcl $0, %%edx; \
+ addl (%%edi), %%eax; \
+ adcl $0, %%edx; \
+ movl %%edx, %%ecx; \
+ stosl; \
+ "
+
+#if defined(POLARSSL_HAVE_SSE2)
+
+#define MULADDC_HUIT \
+ " \
+ movd %%ecx, %%mm1; \
+ movd %%ebx, %%mm0; \
+ movd (%%edi), %%mm3; \
+ paddq %%mm3, %%mm1; \
+ movd (%%esi), %%mm2; \
+ pmuludq %%mm0, %%mm2; \
+ movd 4(%%esi), %%mm4; \
+ pmuludq %%mm0, %%mm4; \
+ movd 8(%%esi), %%mm6; \
+ pmuludq %%mm0, %%mm6; \
+ movd 12(%%esi), %%mm7; \
+ pmuludq %%mm0, %%mm7; \
+ paddq %%mm2, %%mm1; \
+ movd 4(%%edi), %%mm3; \
+ paddq %%mm4, %%mm3; \
+ movd 8(%%edi), %%mm5; \
+ paddq %%mm6, %%mm5; \
+ movd 12(%%edi), %%mm4; \
+ paddq %%mm4, %%mm7; \
+ movd %%mm1, (%%edi); \
+ movd 16(%%esi), %%mm2; \
+ pmuludq %%mm0, %%mm2; \
+ psrlq $32, %%mm1; \
+ movd 20(%%esi), %%mm4; \
+ pmuludq %%mm0, %%mm4; \
+ paddq %%mm3, %%mm1; \
+ movd 24(%%esi), %%mm6; \
+ pmuludq %%mm0, %%mm6; \
+ movd %%mm1, 4(%%edi); \
+ psrlq $32, %%mm1; \
+ movd 28(%%esi), %%mm3; \
+ pmuludq %%mm0, %%mm3; \
+ paddq %%mm5, %%mm1; \
+ movd 16(%%edi), %%mm5; \
+ paddq %%mm5, %%mm2; \
+ movd %%mm1, 8(%%edi); \
+ psrlq $32, %%mm1; \
+ paddq %%mm7, %%mm1; \
+ movd 20(%%edi), %%mm5; \
+ paddq %%mm5, %%mm4; \
+ movd %%mm1, 12(%%edi); \
+ psrlq $32, %%mm1; \
+ paddq %%mm2, %%mm1; \
+ movd 24(%%edi), %%mm5; \
+ paddq %%mm5, %%mm6; \
+ movd %%mm1, 16(%%edi); \
+ psrlq $32, %%mm1; \
+ paddq %%mm4, %%mm1; \
+ movd 28(%%edi), %%mm5; \
+ paddq %%mm5, %%mm3; \
+ movd %%mm1, 20(%%edi); \
+ psrlq $32, %%mm1; \
+ paddq %%mm6, %%mm1; \
+ movd %%mm1, 24(%%edi); \
+ psrlq $32, %%mm1; \
+ paddq %%mm3, %%mm1; \
+ movd %%mm1, 28(%%edi); \
+ addl $32, %%edi; \
+ addl $32, %%esi; \
+ psrlq $32, %%mm1; \
+ movd %%mm1, %%ecx; \
+ "
+
+#define MULADDC_STOP \
+ " \
+ emms; \
+ movl %4, %%ebx; \
+ movl %%ecx, %1; \
+ movl %%edi, %2; \
+ movl %%esi, %3; \
+ " \
+ : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "eax", "ecx", "edx", "esi", "edi" \
+ );
+
+#else
+
+#define MULADDC_STOP \
+ " \
+ movl %4, %%ebx; \
+ movl %%ecx, %1; \
+ movl %%edi, %2; \
+ movl %%esi, %3; \
+ " \
+ : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "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/ap/app/zte_comm/zte_locknet/inc/zctrm_ln_config.h b/ap/app/zte_comm/zte_locknet/inc/zctrm_ln_config.h
new file mode 100755
index 0000000..b0cb2ae
--- /dev/null
+++ b/ap/app/zte_comm/zte_locknet/inc/zctrm_ln_config.h
@@ -0,0 +1,338 @@
+/**
+ * \file config.h
+ *
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * 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
+
+//#include "oss_api.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.
+ *
+ * Requires support for asm() in compiler.
+ *
+ * Used in:
+ * library/timing.c
+ * library/padlock.c
+ * include/polarssl/bn_mul.h
+ *
+ */
+#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 run-time version information functions
+ */
+#define POLARSSL_VERSION_C
+
+/*
+ * 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: library/ssl_tls.c
+ *
+ * This module enabled the following cipher suites:
+ * SSL_RSA_CAMELLIA_128_SHA
+ * SSL_RSA_CAMELLIA_256_SHA
+ * SSL_EDH_RSA_CAMELLIA_256_SHA
+ */
+#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
+ * SSL_EDH_RSA_CAMELLIA_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/ap/app/zte_comm/zte_locknet/inc/zctrm_ln_md5.h b/ap/app/zte_comm/zte_locknet/inc/zctrm_ln_md5.h
new file mode 100755
index 0000000..249e878
--- /dev/null
+++ b/ap/app/zte_comm/zte_locknet/inc/zctrm_ln_md5.h
@@ -0,0 +1,61 @@
+/*
+ ***********************************************************************
+ ** md5.h -- header file for implementation of MD5 **
+ ** RSA Data Security, Inc. MD5 Message-Digest Algorithm **
+ ** Created: 2/17/90 RLR **
+ ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version **
+ ** Revised (for MD5): RLR 4/27/91 **
+ ** -- G modified to have y&~z instead of y&z **
+ ** -- FF, GG, HH modified to add in last register done **
+ ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 **
+ ** -- distinct additive constant for each step **
+ ** -- round 4 added, working mod 7 **
+ ***********************************************************************
+ */
+
+/*
+ ***********************************************************************
+ ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
+ ** **
+ ** License to copy and use this software is granted provided that **
+ ** it is identified as the "RSA Data Security, Inc. MD5 Message- **
+ ** Digest Algorithm" in all material mentioning or referencing this **
+ ** software or this function. **
+ ** **
+ ** License is also granted to make and use derivative works **
+ ** provided that such works are identified as "derived from the RSA **
+ ** Data Security, Inc. MD5 Message-Digest Algorithm" in all **
+ ** material mentioning or referencing the derived work. **
+ ** **
+ ** RSA Data Security, Inc. makes no representations concerning **
+ ** either the merchantability of this software or the suitability **
+ ** of this software for any particular purpose. It is provided "as **
+ ** is" without express or implied warranty of any kind. **
+ ** **
+ ** These notices must be retained in any copies of any part of this **
+ ** documentation and/or software. **
+ ***********************************************************************
+ */
+
+#ifndef ZCTRM_LN_MD5_H
+#define ZCTRM_LN_MD5_H
+
+typedef unsigned long u32_t;
+
+#ifndef SMEMCPY
+#define SMEMCPY(dst,src,len) memcpy(dst,src,len)
+#endif
+
+/* Data structure for MD5 (Message-Digest) computation */
+typedef struct {
+ u32_t i[2]; /* number of _bits_ handled mod 2^64 */
+ u32_t buf[4]; /* scratch buffer */
+ unsigned char in[64]; /* input buffer */
+ unsigned char digest[16]; /* actual digest after md5_final call */
+} md5_ctx;
+
+void md5_init(md5_ctx *ctx);
+void md5_update(md5_ctx *ctx, unsigned char *buf, unsigned int len);
+void md5_final(unsigned char hash[], md5_ctx *ctx);
+
+#endif /* ZCTRM_LN_MD5_H */
diff --git a/ap/app/zte_comm/zte_locknet/inc/zctrm_ln_rsa.h b/ap/app/zte_comm/zte_locknet/inc/zctrm_ln_rsa.h
new file mode 100755
index 0000000..3093f7d
--- /dev/null
+++ b/ap/app/zte_comm/zte_locknet/inc/zctrm_ln_rsa.h
@@ -0,0 +1,355 @@
+/**
+ * \file rsa.h
+ *
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef POLARSSL_RSA_H
+#define POLARSSL_RSA_H
+
+#include "zctrm_ln_bignum.h"
+#include "at_netdog.h"
+
+/*
+ * RSA Error codes
+ */
+#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_TOO_LARGE -0x0470
+#define POLARSSL_ERR_RSA_RNG_FAILED -0x0480
+
+/*
+ * PKCS#1 constants
+ */
+#define SIG_RSA_RAW 0
+#define SIG_RSA_MD2 2
+#define SIG_RSA_MD4 3
+#define SIG_RSA_MD5 4
+#define SIG_RSA_SHA1 5
+#define SIG_RSA_SHA224 14
+#define SIG_RSA_SHA256 11
+#define SIG_RSA_SHA384 12
+#define SIG_RSA_SHA512 13
+
+#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
+
+#define ASN1_STR_CONSTRUCTED_SEQUENCE "\x30"
+#define ASN1_STR_NULL "\x05"
+#define ASN1_STR_OID "\x06"
+#define ASN1_STR_OCTET_STRING "\x04"
+
+#define OID_DIGEST_ALG_MDX "\x2A\x86\x48\x86\xF7\x0D\x02\x00"
+#define OID_HASH_ALG_SHA1 "\x2b\x0e\x03\x02\x1a"
+#define OID_HASH_ALG_SHA2X "\x60\x86\x48\x01\x65\x03\x04\x02\x00"
+
+#define OID_ISO_MEMBER_BODIES "\x2a"
+#define OID_ISO_IDENTIFIED_ORG "\x2b"
+
+/*
+ * ISO Member bodies OID parts
+ */
+#define OID_COUNTRY_US "\x86\x48"
+#define OID_RSA_DATA_SECURITY "\x86\xf7\x0d"
+
+/*
+ * ISO Identified organization OID parts
+ */
+#define OID_OIW_SECSIG_SHA1 "\x0e\x03\x02\x1a"
+
+/*
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm DigestAlgorithmIdentifier,
+ * digest Digest }
+ *
+ * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+ *
+ * Digest ::= OCTET STRING
+ */
+#define ASN1_HASH_MDX \
+( \
+ ASN1_STR_CONSTRUCTED_SEQUENCE "\x20" \
+ ASN1_STR_CONSTRUCTED_SEQUENCE "\x0C" \
+ ASN1_STR_OID "\x08" \
+ OID_DIGEST_ALG_MDX \
+ ASN1_STR_NULL "\x00" \
+ ASN1_STR_OCTET_STRING "\x10" \
+)
+
+#define ASN1_HASH_SHA1 \
+ ASN1_STR_CONSTRUCTED_SEQUENCE "\x21" \
+ ASN1_STR_CONSTRUCTED_SEQUENCE "\x09" \
+ ASN1_STR_OID "\x05" \
+ OID_HASH_ALG_SHA1 \
+ ASN1_STR_NULL "\x00" \
+ ASN1_STR_OCTET_STRING "\x14"
+
+#define ASN1_HASH_SHA2X \
+ ASN1_STR_CONSTRUCTED_SEQUENCE "\x11" \
+ ASN1_STR_CONSTRUCTED_SEQUENCE "\x0d" \
+ ASN1_STR_OID "\x09" \
+ OID_HASH_ALG_SHA2X \
+ ASN1_STR_NULL "\x00" \
+ ASN1_STR_OCTET_STRING "\x00"
+
+/**
+ * \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 */
+}
+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
+ *
+ * \note The hash_id parameter is actually ignored
+ * when using RSA_PKCS_V15 padding.
+ *
+ * \note Currently, RSA_PKCS_V21 padding
+ * is not supported.
+ */
+void rsa_init( rsa_context *ctx,
+ int padding,
+ int hash_id);
+
+/**
+ * \brief Generate an RSA keypair
+ *
+ * \param ctx RSA context that will hold the key
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
+ * \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.
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ */
+int rsa_gen_key( rsa_context *ctx,
+ int (*f_rng)(void *),
+ void *p_rng,
+ 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( const 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( const 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 or assure that
+ * input is smaller than N.
+ *
+ * \note The input and output buffers must be large
+ * enough (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_public( rsa_context *ctx,
+ const 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,
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief Add the message padding, then do an RSA operation
+ *
+ * \param ctx RSA context
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param ilen contains 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 (*f_rng)(void *),
+ void *p_rng,
+ int mode, int ilen,
+ const 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,
+ const 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 SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
+ * \param hashlen message digest length (for SIG_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,
+ const 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 SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
+ * \param hashlen message digest length (for SIG_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,
+ const unsigned char *hash,
+ unsigned char *sig );
+
+/**
+ * \brief Free the components of an RSA key
+ *
+ * \param ctx RSA Context to free
+ */
+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 );
+
+int rsa_private_decrypt(const unsigned char *rsa_ciphertext, unsigned char *rsa_decrypted);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* rsa.h */
diff --git a/ap/app/zte_comm/zte_locknet/inc/zctrm_locknet.h b/ap/app/zte_comm/zte_locknet/inc/zctrm_locknet.h
new file mode 100755
index 0000000..9761bf6
--- /dev/null
+++ b/ap/app/zte_comm/zte_locknet/inc/zctrm_locknet.h
@@ -0,0 +1,177 @@
+#ifndef __ZCTRM_LOCKNET_H__
+#define __ZCTRM_LOCKNET_H__
+
+#include "at_context.h"
+#include <sys/ioctl.h>
+#include "libcpnv.h"
+#include "RONvConfig.h"
+
+#define EFUSE_IOC_MAGIC 'E'
+
+#define EFUSE_GET_DATA _IOWR(EFUSE_IOC_MAGIC, 1, char *)
+
+
+#define LOCKNET_KEY_LEN 16
+#define ZCTRM_LOCKNET_AT_LEN 64
+#define KEY_LEN 128
+
+#define IDENTIFIER_GID1 28478
+#define IDENTIFIER_GID2 28479
+
+#define LOCKNET_ITEM_NUM 6
+#define LOCKNET_FIRST_NUM 42
+#define LOCKNET_MAX_NUM 50
+#define LOCKNET_MAX_AT_LEN 560
+
+#define EXT_SUCCESS 0
+#define EXT_ERROR -1
+
+// 2 Bytes
+#define USED_GID_LEN 4
+#define MAX_AMT_AT_LEN 1024
+#define MAX_RETRY_TIMES 10
+#define LIST_MCCMNC_LEN 4
+#define LIST_IMSI_LEN 2
+#define LIST_GID_LEN 256
+#define LIST_LEN (LIST_MCCMNC_LEN*2+LIST_IMSI_LEN*2+LIST_GID_LEN*2)
+#define MAX_IMSI_LEN 32
+#define AT_STR_LEN 64
+//lock state
+#define AMT_LOCKNET_BASE OS_FLASH_ROW_OFFSET_FROM_NV//0x000D0000
+#define AMT_LOCKNET_TIMES (AMT_LOCKNET_BASE + 0x40)
+#define AMT_LOCKNET_KEY (AMT_LOCKNET_BASE + 0x80)
+#define AMT_LOCKNET_USRKEY (AMT_LOCKNET_BASE + 0x100)
+#define AMT_LOCKNET_SIGN (AMT_LOCKNET_BASE + 0x120)
+#define AMT_LOCKNET_LIST (AMT_LOCKNET_BASE + 0x1A0)
+
+/*Êý¾Ý½á¹¹¶¨ÒåÇø*/
+typedef struct
+{
+ unsigned int pubKeyRsaE[32];
+ unsigned int pubKeyRsaN[32];
+ unsigned int secureFlag;
+ unsigned int pubKeyHash[4];
+ unsigned int secureDevId[3];
+}T_ZDrvEfuse_Secure;
+
+
+typedef enum
+{
+ ENCRYPT_INITING = 0,
+ ENCRYPT_ERROR,
+ ENCRYPT_LOCK,
+ ENCRYPT_UNLOCK_CORRECT,
+}T_zAt_SecStatue;
+
+typedef struct
+{
+ UINT8 mcc[LIST_MCCMNC_LEN];
+ UINT8 mnc[LIST_MCCMNC_LEN];
+ UINT8 imsi6[LIST_IMSI_LEN];
+ UINT8 imsi7[LIST_IMSI_LEN];
+ UINT8 gid1[LIST_GID_LEN];
+ UINT8 gid2[LIST_GID_LEN];
+}T_zCtrm_LockListPara;
+
+typedef struct
+{
+ UINT8 cmd[2];
+ UINT8 code[32];
+} T_zAt_LockListAuthRes;
+
+typedef enum
+{
+ PARA_MCC = 0,
+ PARA_MNC,
+ PARA_IMSI6,
+ PARA_IMSI7,
+ PARA_GID1,
+ PARA_GID2,
+}T_zCtrm_LockPara;
+
+
+typedef enum
+{
+ LOCKFLAG_ERROR = 0,
+ ALREADY_UNLOCKED,
+ LOCKED,
+ NEVER_LOCKED = 0xFFFFFFFF,
+}T_zCtrm_LockLevel;
+
+typedef enum
+{
+ NO_ACTION = 0,
+ NET_LOCK,
+ SIM_LOCK,
+ NET_SIM_LOCK,
+
+}T_zCtrm_SecItems;
+
+typedef enum
+{
+ RESULT_ERROR = 0,//´íÎó
+ RESULT_LOCKED,//²»ÔÊÐíËÑÍø
+ RESULT_UNLOCKED,//ÔÊÐíËÑÍø
+}T_zCtrm_RESULT;
+
+typedef enum
+{
+ READ_ERROR=0,
+ LOCKKEY_ISNULL,
+ READ_SUCCESS,
+}T_zCtrm_ReadResult;
+
+
+typedef struct
+{
+ UINT16 cardMode;
+ UINT16 mncLen;
+ UINT32 fileLen;
+ UINT8 simImsi[MAX_IMSI_LEN];
+}T_zCtrm_SIMPara;
+
+typedef enum
+{
+ CARDMODE_UNKNOW = 0,
+ CARDMODE_SIM,
+ CARDMODE_USIM,
+}T_zCtrm_SimType;
+
+typedef enum
+{
+ GET_NONE = 0,
+ GET_GID1LEN,
+ GET_GID1,
+ GET_GID2LEN,
+ GET_GID2,
+ GET_MNCLEN
+}T_zCtrm_CrsmReq;
+
+/**
+ * @brief ËøÍøÏìÓ¦ÏûϢͨÓýṹÌ壬¶ÔÓ¦ÏûÏ¢MSG_CMD_LOCKNET_AUTH_RSP/MSG_CMD_LOCKNET_UNLOCK_RSP
+ * @param result ½á¹ûÂë AT_RSP_OK/AT_RSP_ERR
+ * @param errcode Èç¹û¼øÈ¨Ê§°Ü£¬·µ»Ø´íÎóÂë
+ */
+typedef struct
+{
+ int result;
+ char errcode[8];
+}AT_LOCKNET_RSP_INFO;
+
+int zCtrm_LocknetAuthProc(MSG_BUF *msg);
+int zCtrm_LocknetListSet(MSG_BUF *msg);
+int zCtrm_LocknetKeyProc(MSG_BUF *msg);
+int zCtrm_LocknetAmtStatus(MSG_BUF *msg);
+int zCtrm_LocknetDigestGet(MSG_BUF *msg);
+int zCtrm_LocknetSignSet(MSG_BUF *msg);
+int zCtrm_LocknetLevel(MSG_BUF *msg);
+int zCtrm_LocknetListGetProc(MSG_BUF *msg);
+int zCtrm_makeLocknetAuth(MSG_BUF *msg);
+int zCtrm_LocknetUnlockTimes(MSG_BUF *msg);
+int zCtrm_LocknetStatus(MSG_BUF *msg);
+int zCtrm_LocknetUnlock(MSG_BUF *msg);
+int zCtrm_makeLocknetAuth(MSG_BUF *msg);
+/*Íⲿº¯Êý,½Ó¿Ú*/
+extern void zDrvEfuse_GetSecureMsg(T_ZDrvEfuse_Secure *secure);
+
+#endif
diff --git a/ap/app/zte_comm/zte_locknet/src/zctrm_ln_bignum.c b/ap/app/zte_comm/zte_locknet/src/zctrm_ln_bignum.c
new file mode 100755
index 0000000..2cfc932
--- /dev/null
+++ b/ap/app/zte_comm/zte_locknet/src/zctrm_ln_bignum.c
@@ -0,0 +1,2043 @@
+/*
+ * Multi-precision integer library
+ *
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+/*
+ * This MPI implementation is based on:
+ *
+ * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
+ * http://www.stillhq.com/extracted/gnupg-api/mpi/
+ * http://math.libtomcrypt.com/files/tommath.pdf
+ */
+
+#include "zctrm_ln_config.h"
+
+#if defined(POLARSSL_BIGNUM_C)
+
+#include "zctrm_ln_bignum.h"
+#include "zctrm_ln_bnmul.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#define ciL ((int) sizeof(t_int)) /* chars in limb */
+#define biL (ciL << 3) /* bits in limb */
+#define biH (ciL << 2) /* half limb size */
+
+/*
+ * Convert between bits/chars and number of limbs
+ */
+#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL)
+#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL)
+
+/*
+ * Initialize one or more mpi
+ */
+void mpi_init( mpi *X, ... )
+{
+ va_list args;
+
+ va_start( args, X );
+
+ while( X != NULL )
+ {
+ X->s = 1;
+ X->n = 0;
+ X->p = NULL;
+
+ X = va_arg( args, mpi* );
+ }
+
+ va_end( args );
+}
+
+/*
+ * Unallocate one or more mpi
+ */
+void mpi_free( mpi *X, ... )
+{
+ va_list args;
+
+ va_start( args, X );
+
+ while( X != NULL )
+ {
+ if( X->p != NULL )
+ {
+ memset( X->p, 0, X->n * ciL );
+ free( X->p );
+ }
+
+ X->s = 1;
+ X->n = 0;
+ X->p = NULL;
+
+ X = va_arg( args, mpi* );
+ }
+
+ va_end( args );
+}
+
+/*
+ * Enlarge to the specified number of limbs
+ */
+int mpi_grow( mpi *X, int nblimbs )
+{
+ t_int *p;
+
+ if( X->n < nblimbs )
+ {
+ if( ( p = (t_int *) malloc( nblimbs * ciL ) ) == NULL )
+ return( 1 );
+
+ memset( p, 0, nblimbs * ciL );
+
+ if( X->p != NULL )
+ {
+ memcpy( p, X->p, X->n * ciL );
+ memset( X->p, 0, X->n * ciL );
+ free( X->p );
+ }
+
+ X->n = nblimbs;
+ X->p = p;
+ }
+
+ return( 0 );
+}
+
+/*
+ * Copy the contents of Y into X
+ */
+int mpi_copy( mpi *X, const mpi *Y )
+{
+ int ret, i;
+
+ if( X == Y )
+ return( 0 );
+
+ for( i = Y->n - 1; i > 0; i-- )
+ if( Y->p[i] != 0 )
+ break;
+ i++;
+
+ X->s = Y->s;
+
+ MPI_CHK( mpi_grow( X, i ) );
+
+ memset( X->p, 0, X->n * ciL );
+ memcpy( X->p, Y->p, i * ciL );
+
+cleanup:
+
+ return( ret );
+}
+
+/*
+ * Swap the contents of X and Y
+ */
+void mpi_swap( mpi *X, mpi *Y )
+{
+ mpi T;
+
+ memcpy( &T, X, sizeof( mpi ) );
+ memcpy( X, Y, sizeof( mpi ) );
+ memcpy( Y, &T, sizeof( mpi ) );
+}
+
+/*
+ * Set value from integer
+ */
+int mpi_lset( mpi *X, int z )
+{
+ int ret;
+
+ MPI_CHK( mpi_grow( X, 1 ) );
+ memset( X->p, 0, X->n * ciL );
+
+ X->p[0] = ( z < 0 ) ? -z : z;
+ X->s = ( z < 0 ) ? -1 : 1;
+
+cleanup:
+
+ return( ret );
+}
+
+/*
+ * Return the number of least significant bits
+ */
+int mpi_lsb( const mpi *X )
+{
+ int i, j, count = 0;
+
+ for( i = 0; i < X->n; i++ )
+ for( j = 0; j < (int) biL; j++, count++ )
+ if( ( ( X->p[i] >> j ) & 1 ) != 0 )
+ return( count );
+
+ return( 0 );
+}
+
+/*
+ * Return the number of most significant bits
+ */
+int mpi_msb( const mpi *X )
+{
+ int i, j;
+
+ for( i = X->n - 1; i > 0; i-- )
+ if( X->p[i] != 0 )
+ break;
+
+ for( j = biL - 1; j >= 0; j-- )
+ if( ( ( X->p[i] >> j ) & 1 ) != 0 )
+ break;
+
+ return( ( i * biL ) + j + 1 );
+}
+
+/*
+ * Return the total size in bytes
+ */
+int mpi_size( const mpi *X )
+{
+ return( ( mpi_msb( X ) + 7 ) >> 3 );
+}
+
+/*
+ * Convert an ASCII character to digit value
+ */
+static int mpi_get_digit( t_int *d, int radix, char c )
+{
+ *d = 255;
+
+ if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
+ if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
+ if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
+
+ if( *d >= (t_int) radix )
+ return( POLARSSL_ERR_MPI_INVALID_CHARACTER );
+
+ return( 0 );
+}
+
+/*
+ * Import from an ASCII string
+ */
+int mpi_read_string( mpi *X, int radix, const char *s )
+{
+ int ret, i, j, n, slen;
+ t_int d;
+ mpi T;
+
+ if( radix < 2 || radix > 16 )
+ return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+ mpi_init( &T, NULL );
+
+ slen = strlen( s );
+
+ if( radix == 16 )
+ {
+ n = BITS_TO_LIMBS( slen << 2 );
+
+ MPI_CHK( mpi_grow( X, n ) );
+ MPI_CHK( mpi_lset( X, 0 ) );
+
+ for( i = slen - 1, j = 0; i >= 0; i--, j++ )
+ {
+ if( i == 0 && s[i] == '-' )
+ {
+ X->s = -1;
+ break;
+ }
+
+ MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
+ X->p[j / (2 * ciL)] |= d << ( (j % (2 * ciL)) << 2 );
+ }
+ }
+ else
+ {
+ MPI_CHK( mpi_lset( X, 0 ) );
+
+ for( i = 0; i < slen; i++ )
+ {
+ if( i == 0 && s[i] == '-' )
+ {
+ X->s = -1;
+ continue;
+ }
+
+ MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
+ MPI_CHK( mpi_mul_int( &T, X, radix ) );
+
+ if( X->s == 1 )
+ {
+ MPI_CHK( mpi_add_int( X, &T, d ) );
+ }
+ else
+ {
+ MPI_CHK( mpi_sub_int( X, &T, d ) );
+ }
+ }
+ }
+
+cleanup:
+
+ mpi_free( &T, NULL );
+
+ return( ret );
+}
+
+/*
+ * Helper to write the digits high-order first
+ */
+static int mpi_write_hlp( mpi *X, int radix, char **p )
+{
+ int ret;
+ t_int r;
+
+ if( radix < 2 || radix > 16 )
+ return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+ MPI_CHK( mpi_mod_int( &r, X, radix ) );
+ MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
+
+ if( mpi_cmp_int( X, 0 ) != 0 )
+ MPI_CHK( mpi_write_hlp( X, radix, p ) );
+
+ if( r < 10 )
+ *(*p)++ = (char)( r + 0x30 );
+ else
+ *(*p)++ = (char)( r + 0x37 );
+
+cleanup:
+
+ return( ret );
+}
+
+/*
+ * Export into an ASCII string
+ */
+int mpi_write_string( const mpi *X, int radix, char *s, int *slen )
+{
+ int ret = 0, n;
+ char *p;
+ mpi T;
+
+ if( radix < 2 || radix > 16 )
+ return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+ n = mpi_msb( X );
+ if( radix >= 4 ) n >>= 1;
+ if( radix >= 16 ) n >>= 1;
+ n += 3;
+
+ if( *slen < n )
+ {
+ *slen = n;
+ return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
+ }
+
+ p = s;
+ mpi_init( &T, NULL );
+
+ if( X->s == -1 )
+ *p++ = '-';
+
+ if( radix == 16 )
+ {
+ int c, i, j, k;
+
+ for( i = X->n - 1, k = 0; i >= 0; i-- )
+ {
+ for( j = ciL - 1; j >= 0; j-- )
+ {
+ c = ( X->p[i] >> (j << 3) ) & 0xFF;
+
+ if( c == 0 && k == 0 && (i + j) != 0 )
+ continue;
+
+ p += sprintf( p, "%02X", c );
+ k = 1;
+ }
+ }
+ }
+ else
+ {
+ MPI_CHK( mpi_copy( &T, X ) );
+
+ if( T.s == -1 )
+ T.s = 1;
+
+ MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
+ }
+
+ *p++ = '\0';
+ *slen = p - s;
+
+cleanup:
+
+ mpi_free( &T, NULL );
+
+ return( ret );
+}
+#if 0
+/*
+ * Read X from an opened file
+ */
+int mpi_read_file( mpi *X, int radix, FILE *fin )
+{
+ t_int d;
+ int slen;
+ char *p;
+ char s[1024];
+
+ memset( s, 0, sizeof( s ) );
+ if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
+ return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
+
+ slen = strlen( s );
+ if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
+ if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
+
+ p = s + slen;
+ while( --p >= s )
+ if( mpi_get_digit( &d, radix, *p ) != 0 )
+ break;
+
+ return( mpi_read_string( X, radix, p + 1 ) );
+}
+
+/*
+ * Write X into an opened file (or stdout if fout == NULL)
+ */
+int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout )
+{
+ int n, ret;
+ size_t slen;
+ size_t plen;
+ char s[2048];
+
+ n = sizeof( s );
+ memset( s, 0, n );
+ n -= 2;
+
+ MPI_CHK( mpi_write_string( X, radix, s, (int *) &n ) );
+
+ if( p == NULL ) p = "";
+
+ plen = strlen( p );
+ slen = strlen( s );
+ s[slen++] = '\r';
+ s[slen++] = '\n';
+
+ if( fout != NULL )
+ {
+ if( fwrite( p, 1, plen, fout ) != plen ||
+ fwrite( s, 1, slen, fout ) != slen )
+ return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
+ }
+ else
+ printf( "%s%s", p, s );
+
+cleanup:
+
+ return( ret );
+}
+#endif
+/*
+ * Import X from unsigned binary data, big endian
+ */
+int mpi_read_binary( mpi *X, const unsigned char *buf, int buflen )
+{
+ int ret, i, j, n;
+
+ for( n = 0; n < buflen; n++ )
+ if( buf[n] != 0 )
+ break;
+
+ MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
+ MPI_CHK( mpi_lset( X, 0 ) );
+
+ for( i = buflen - 1, j = 0; i >= n; i--, j++ )
+ X->p[j / ciL] |= ((t_int) buf[i]) << ((j % ciL) << 3);
+
+cleanup:
+
+ return( ret );
+}
+
+/*
+ * Export X into unsigned binary data, big endian
+ */
+int mpi_write_binary( const mpi *X, unsigned char *buf, int buflen )
+{
+ int i, j, n;
+
+ n = mpi_size( X );
+
+ if( buflen < n )
+ return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
+
+ memset( buf, 0, buflen );
+
+ for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
+ buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
+
+ return( 0 );
+}
+
+/*
+ * Left-shift: X <<= count
+ */
+int mpi_shift_l( mpi *X, int count )
+{
+ int ret, i, v0, t1;
+ t_int r0 = 0, r1;
+
+ v0 = count / (biL );
+ t1 = count & (biL - 1);
+
+ i = mpi_msb( X ) + count;
+
+ if( X->n * (int) biL < i )
+ MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
+
+ ret = 0;
+
+ /*
+ * shift by count / limb_size
+ */
+ if( v0 > 0 )
+ {
+ for( i = X->n - 1; i >= v0; i-- )
+ X->p[i] = X->p[i - v0];
+
+ for( ; i >= 0; i-- )
+ X->p[i] = 0;
+ }
+
+ /*
+ * shift by count % limb_size
+ */
+ if( t1 > 0 )
+ {
+ for( i = v0; i < X->n; i++ )
+ {
+ r1 = X->p[i] >> (biL - t1);
+ X->p[i] <<= t1;
+ X->p[i] |= r0;
+ r0 = r1;
+ }
+ }
+
+cleanup:
+
+ return( ret );
+}
+
+/*
+ * Right-shift: X >>= count
+ */
+int mpi_shift_r( mpi *X, int count )
+{
+ int i, v0, v1;
+ t_int r0 = 0, r1;
+
+ v0 = count / biL;
+ v1 = count & (biL - 1);
+
+ /*
+ * shift by count / limb_size
+ */
+ if( v0 > 0 )
+ {
+ for( i = 0; i < X->n - v0; i++ )
+ X->p[i] = X->p[i + v0];
+
+ for( ; i < X->n; i++ )
+ X->p[i] = 0;
+ }
+
+ /*
+ * shift by count % limb_size
+ */
+ if( v1 > 0 )
+ {
+ for( i = X->n - 1; i >= 0; i-- )
+ {
+ r1 = X->p[i] << (biL - v1);
+ X->p[i] >>= v1;
+ X->p[i] |= r0;
+ r0 = r1;
+ }
+ }
+
+ return( 0 );
+}
+
+/*
+ * Compare unsigned values
+ */
+int mpi_cmp_abs( const mpi *X, const mpi *Y )
+{
+ int i, j;
+
+ for( i = X->n - 1; i >= 0; i-- )
+ if( X->p[i] != 0 )
+ break;
+
+ for( j = Y->n - 1; j >= 0; j-- )
+ if( Y->p[j] != 0 )
+ break;
+
+ if( i < 0 && j < 0 )
+ return( 0 );
+
+ if( i > j ) return( 1 );
+ if( j > i ) return( -1 );
+
+ for( ; i >= 0; i-- )
+ {
+ if( X->p[i] > Y->p[i] ) return( 1 );
+ if( X->p[i] < Y->p[i] ) return( -1 );
+ }
+
+ return( 0 );
+}
+
+/*
+ * Compare signed values
+ */
+int mpi_cmp_mpi( const mpi *X, const mpi *Y )
+{
+ int i, j;
+
+ for( i = X->n - 1; i >= 0; i-- )
+ if( X->p[i] != 0 )
+ break;
+
+ for( j = Y->n - 1; j >= 0; j-- )
+ if( Y->p[j] != 0 )
+ break;
+
+ if( i < 0 && j < 0 )
+ return( 0 );
+
+ if( i > j ) return( X->s );
+ if( j > i ) return( -X->s );
+
+ if( X->s > 0 && Y->s < 0 ) return( 1 );
+ if( Y->s > 0 && X->s < 0 ) return( -1 );
+
+ for( ; i >= 0; i-- )
+ {
+ if( X->p[i] > Y->p[i] ) return( X->s );
+ if( X->p[i] < Y->p[i] ) return( -X->s );
+ }
+
+ return( 0 );
+}
+
+/*
+ * Compare signed values
+ */
+int mpi_cmp_int( const mpi *X, int z )
+{
+ mpi Y;
+ t_int p[1];
+
+ *p = ( z < 0 ) ? -z : z;
+ Y.s = ( z < 0 ) ? -1 : 1;
+ Y.n = 1;
+ Y.p = p;
+
+ return( mpi_cmp_mpi( X, &Y ) );
+}
+
+/*
+ * Unsigned addition: X = |A| + |B| (HAC 14.7)
+ */
+int mpi_add_abs( mpi *X, const mpi *A, const mpi *B )
+{
+ int ret, i, j;
+ t_int *o, *p, c;
+
+ if( X == B )
+ {
+ const mpi *T = A; A = X; B = T;
+ }
+
+ if( X != A )
+ MPI_CHK( mpi_copy( X, A ) );
+
+ /*
+ * X should always be positive as a result of unsigned additions.
+ */
+ X->s = 1;
+
+ for( j = B->n - 1; j >= 0; j-- )
+ if( B->p[j] != 0 )
+ break;
+
+ MPI_CHK( mpi_grow( X, j + 1 ) );
+
+ o = B->p; p = X->p; c = 0;
+
+ for( i = 0; i <= j; i++, o++, p++ )
+ {
+ *p += c; c = ( *p < c );
+ *p += *o; c += ( *p < *o );
+ }
+
+ while( c != 0 )
+ {
+ if( i >= X->n )
+ {
+ MPI_CHK( mpi_grow( X, i + 1 ) );
+ p = X->p + i;
+ }
+
+ *p += c; c = ( *p < c ); i++;
+ }
+
+cleanup:
+
+ return( ret );
+}
+
+/*
+ * Helper for mpi substraction
+ */
+static void mpi_sub_hlp( int n, t_int *s, t_int *d )
+{
+ int i;
+ t_int c, z;
+
+ for( i = c = 0; i < n; i++, s++, d++ )
+ {
+ z = ( *d < c ); *d -= c;
+ c = ( *d < *s ) + z; *d -= *s;
+ }
+
+ while( c != 0 )
+ {
+ z = ( *d < c ); *d -= c;
+ c = z; i++; d++;
+ }
+}
+
+/*
+ * Unsigned substraction: X = |A| - |B| (HAC 14.9)
+ */
+int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B )
+{
+ mpi TB;
+ int ret, n;
+
+ if( mpi_cmp_abs( A, B ) < 0 )
+ return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
+
+ mpi_init( &TB, NULL );
+
+ if( X == B )
+ {
+ MPI_CHK( mpi_copy( &TB, B ) );
+ B = &TB;
+ }
+
+ if( X != A )
+ MPI_CHK( mpi_copy( X, A ) );
+
+ /*
+ * X should always be positive as a result of unsigned substractions.
+ */
+ X->s = 1;
+
+ ret = 0;
+
+ for( n = B->n - 1; n >= 0; n-- )
+ if( B->p[n] != 0 )
+ break;
+
+ mpi_sub_hlp( n + 1, B->p, X->p );
+
+cleanup:
+
+ mpi_free( &TB, NULL );
+
+ return( ret );
+}
+
+/*
+ * Signed addition: X = A + B
+ */
+int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B )
+{
+ int ret, s = A->s;
+
+ if( A->s * B->s < 0 )
+ {
+ if( mpi_cmp_abs( A, B ) >= 0 )
+ {
+ MPI_CHK( mpi_sub_abs( X, A, B ) );
+ X->s = s;
+ }
+ else
+ {
+ MPI_CHK( mpi_sub_abs( X, B, A ) );
+ X->s = -s;
+ }
+ }
+ else
+ {
+ MPI_CHK( mpi_add_abs( X, A, B ) );
+ X->s = s;
+ }
+
+cleanup:
+
+ return( ret );
+}
+
+/*
+ * Signed substraction: X = A - B
+ */
+int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B )
+{
+ int ret, s = A->s;
+
+ if( A->s * B->s > 0 )
+ {
+ if( mpi_cmp_abs( A, B ) >= 0 )
+ {
+ MPI_CHK( mpi_sub_abs( X, A, B ) );
+ X->s = s;
+ }
+ else
+ {
+ MPI_CHK( mpi_sub_abs( X, B, A ) );
+ X->s = -s;
+ }
+ }
+ else
+ {
+ MPI_CHK( mpi_add_abs( X, A, B ) );
+ X->s = s;
+ }
+
+cleanup:
+
+ return( ret );
+}
+
+/*
+ * Signed addition: X = A + b
+ */
+int mpi_add_int( mpi *X, const mpi *A, int b )
+{
+ mpi _B;
+ t_int p[1];
+
+ p[0] = ( b < 0 ) ? -b : b;
+ _B.s = ( b < 0 ) ? -1 : 1;
+ _B.n = 1;
+ _B.p = p;
+
+ return( mpi_add_mpi( X, A, &_B ) );
+}
+
+/*
+ * Signed substraction: X = A - b
+ */
+int mpi_sub_int( mpi *X, const mpi *A, int b )
+{
+ mpi _B;
+ t_int p[1];
+
+ p[0] = ( b < 0 ) ? -b : b;
+ _B.s = ( b < 0 ) ? -1 : 1;
+ _B.n = 1;
+ _B.p = p;
+
+ return( mpi_sub_mpi( X, A, &_B ) );
+}
+
+/*
+ * Helper for mpi multiplication
+ */
+static void mpi_mul_hlp( int i, t_int *s, t_int *d, t_int b )
+{
+ t_int c = 0, t = 0;
+
+#if defined(MULADDC_HUIT)
+ for( ; i >= 8; i -= 8 )
+ {
+ MULADDC_INIT
+ MULADDC_HUIT
+ MULADDC_STOP
+ }
+
+ for( ; i > 0; i-- )
+ {
+ MULADDC_INIT
+ MULADDC_CORE
+ MULADDC_STOP
+ }
+#else
+ for( ; i >= 16; i -= 16 )
+ {
+ MULADDC_INIT
+ MULADDC_CORE MULADDC_CORE
+ MULADDC_CORE MULADDC_CORE
+ MULADDC_CORE MULADDC_CORE
+ MULADDC_CORE MULADDC_CORE
+
+ MULADDC_CORE MULADDC_CORE
+ MULADDC_CORE MULADDC_CORE
+ MULADDC_CORE MULADDC_CORE
+ MULADDC_CORE MULADDC_CORE
+ MULADDC_STOP
+ }
+
+ for( ; i >= 8; i -= 8 )
+ {
+ MULADDC_INIT
+ MULADDC_CORE MULADDC_CORE
+ MULADDC_CORE MULADDC_CORE
+
+ MULADDC_CORE MULADDC_CORE
+ MULADDC_CORE MULADDC_CORE
+ MULADDC_STOP
+ }
+
+ for( ; i > 0; i-- )
+ {
+ MULADDC_INIT
+ MULADDC_CORE
+ MULADDC_STOP
+ }
+#endif
+
+ t++;
+
+ do {
+ *d += c; c = ( *d < c ); d++;
+ }
+ while( c != 0 );
+}
+
+/*
+ * Baseline multiplication: X = A * B (HAC 14.12)
+ */
+int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B )
+{
+ int ret, i, j;
+ mpi TA, TB;
+
+ mpi_init( &TA, &TB, NULL );
+
+ if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
+ if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
+
+ for( i = A->n - 1; i >= 0; i-- )
+ if( A->p[i] != 0 )
+ break;
+
+ for( j = B->n - 1; j >= 0; j-- )
+ if( B->p[j] != 0 )
+ break;
+
+ MPI_CHK( mpi_grow( X, i + j + 2 ) );
+ MPI_CHK( mpi_lset( X, 0 ) );
+
+ for( i++; j >= 0; j-- )
+ mpi_mul_hlp( i, A->p, X->p + j, B->p[j] );
+
+ X->s = A->s * B->s;
+
+cleanup:
+
+ mpi_free( &TB, &TA, NULL );
+
+ return( ret );
+}
+
+/*
+ * Baseline multiplication: X = A * b
+ */
+int mpi_mul_int( mpi *X, const mpi *A, t_int b )
+{
+ mpi _B;
+ t_int p[1];
+
+ _B.s = 1;
+ _B.n = 1;
+ _B.p = p;
+ p[0] = b;
+
+ return( mpi_mul_mpi( X, A, &_B ) );
+}
+
+/*
+ * Division by mpi: A = Q * B + R (HAC 14.20)
+ */
+int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
+{
+ int ret, i, n, t, k;
+ mpi X, Y, Z, T1, T2;
+
+ if( mpi_cmp_int( B, 0 ) == 0 )
+ return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
+
+ mpi_init( &X, &Y, &Z, &T1, &T2, NULL );
+
+ if( mpi_cmp_abs( A, B ) < 0 )
+ {
+ if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
+ if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
+ return( 0 );
+ }
+
+ MPI_CHK( mpi_copy( &X, A ) );
+ MPI_CHK( mpi_copy( &Y, B ) );
+ X.s = Y.s = 1;
+
+ MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
+ MPI_CHK( mpi_lset( &Z, 0 ) );
+ MPI_CHK( mpi_grow( &T1, 2 ) );
+ MPI_CHK( mpi_grow( &T2, 3 ) );
+
+ k = mpi_msb( &Y ) % biL;
+ if( k < (int) biL - 1 )
+ {
+ k = biL - 1 - k;
+ MPI_CHK( mpi_shift_l( &X, k ) );
+ MPI_CHK( mpi_shift_l( &Y, k ) );
+ }
+ else k = 0;
+
+ n = X.n - 1;
+ t = Y.n - 1;
+ MPI_CHK(mpi_shift_l( &Y, biL * (n - t) ));
+
+ while( mpi_cmp_mpi( &X, &Y ) >= 0 )
+ {
+ Z.p[n - t]++;
+ MPI_CHK(mpi_sub_mpi( &X, &X, &Y ));
+ }
+ MPI_CHK(mpi_shift_r( &Y, biL * (n - t) ));
+
+ for( i = n; i > t ; i-- )
+ {
+ if( X.p[i] >= Y.p[t] )
+ Z.p[i - t - 1] = ~0;
+ else
+ {
+#if defined(POLARSSL_HAVE_LONGLONG)
+ t_dbl r;
+
+ r = (t_dbl) X.p[i] << biL;
+ r |= (t_dbl) X.p[i - 1];
+ r /= Y.p[t];
+ if( r > ((t_dbl) 1 << biL) - 1)
+ r = ((t_dbl) 1 << biL) - 1;
+
+ Z.p[i - t - 1] = (t_int) r;
+#else
+ /*
+ * __udiv_qrnnd_c, from gmp/longlong.h
+ */
+ t_int q0, q1, r0, r1;
+ t_int d0, d1, d, m;
+
+ d = Y.p[t];
+ d0 = ( d << biH ) >> biH;
+ d1 = ( d >> biH );
+
+ q1 = X.p[i] / d1;
+ r1 = X.p[i] - d1 * q1;
+ r1 <<= biH;
+ r1 |= ( X.p[i - 1] >> biH );
+
+ m = q1 * d0;
+ if( r1 < m )
+ {
+ q1--, r1 += d;
+ while( r1 >= d && r1 < m )
+ q1--, r1 += d;
+ }
+ r1 -= m;
+
+ q0 = r1 / d1;
+ r0 = r1 - d1 * q0;
+ r0 <<= biH;
+ r0 |= ( X.p[i - 1] << biH ) >> biH;
+
+ m = q0 * d0;
+ if( r0 < m )
+ {
+ q0--, r0 += d;
+ while( r0 >= d && r0 < m )
+ q0--, r0 += d;
+ }
+ r0 -= m;
+
+ Z.p[i - t - 1] = ( q1 << biH ) | q0;
+#endif
+ }
+
+ Z.p[i - t - 1]++;
+ do
+ {
+ Z.p[i - t - 1]--;
+
+ MPI_CHK( mpi_lset( &T1, 0 ) );
+ T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
+ T1.p[1] = Y.p[t];
+ MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
+
+ MPI_CHK( mpi_lset( &T2, 0 ) );
+ T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
+ T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
+ T2.p[2] = X.p[i];
+ }
+ while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
+
+ MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
+ MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
+ MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
+
+ if( mpi_cmp_int( &X, 0 ) < 0 )
+ {
+ MPI_CHK( mpi_copy( &T1, &Y ) );
+ MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
+ MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
+ Z.p[i - t - 1]--;
+ }
+ }
+
+ if( Q != NULL )
+ {
+ MPI_CHK(mpi_copy( Q, &Z ));
+ Q->s = A->s * B->s;
+ }
+
+ if( R != NULL )
+ {
+ MPI_CHK(mpi_shift_r( &X, k ));
+ MPI_CHK(mpi_copy( R, &X ));
+
+ R->s = A->s;
+ if( mpi_cmp_int( R, 0 ) == 0 )
+ R->s = 1;
+ }
+
+cleanup:
+
+ mpi_free( &X, &Y, &Z, &T1, &T2, NULL );
+
+ return( ret );
+}
+
+/*
+ * Division by int: A = Q * b + R
+ *
+ * Returns 0 if successful
+ * 1 if memory allocation failed
+ * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
+ */
+int mpi_div_int( mpi *Q, mpi *R, const mpi *A, int b )
+{
+ mpi _B;
+ t_int p[1];
+
+ p[0] = ( b < 0 ) ? -b : b;
+ _B.s = ( b < 0 ) ? -1 : 1;
+ _B.n = 1;
+ _B.p = p;
+
+ return( mpi_div_mpi( Q, R, A, &_B ) );
+}
+
+/*
+ * Modulo: R = A mod B
+ */
+int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B )
+{
+ int ret;
+
+ if( mpi_cmp_int( B, 0 ) < 0 )
+ return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
+
+ MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
+
+ while( mpi_cmp_int( R, 0 ) < 0 )
+ MPI_CHK( mpi_add_mpi( R, R, B ) );
+
+ while( mpi_cmp_mpi( R, B ) >= 0 )
+ MPI_CHK( mpi_sub_mpi( R, R, B ) );
+
+cleanup:
+
+ return( ret );
+}
+
+/*
+ * Modulo: r = A mod b
+ */
+int mpi_mod_int( t_int *r, const mpi *A, int b )
+{
+ int i;
+ t_int x, y, z;
+
+ if( b == 0 )
+ return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
+
+ if( b < 0 )
+ return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
+
+ /*
+ * handle trivial cases
+ */
+ if( b == 1 )
+ {
+ *r = 0;
+ return( 0 );
+ }
+
+ if( b == 2 )
+ {
+ *r = A->p[0] & 1;
+ return( 0 );
+ }
+
+ /*
+ * general case
+ */
+ for( i = A->n - 1, y = 0; i >= 0; i-- )
+ {
+ x = A->p[i];
+ y = ( y << biH ) | ( x >> biH );
+ z = y / b;
+ y -= z * b;
+
+ x <<= biH;
+ y = ( y << biH ) | ( x >> biH );
+ z = y / b;
+ y -= z * b;
+ }
+
+ /*
+ * If A is negative, then the current y represents a negative value.
+ * Flipping it to the positive side.
+ */
+ if( A->s < 0 && y != 0 )
+ y = b - y;
+
+ *r = y;
+
+ return( 0 );
+}
+
+/*
+ * Fast Montgomery initialization (thanks to Tom St Denis)
+ */
+static void mpi_montg_init( t_int *mm, const mpi *N )
+{
+ t_int x, m0 = N->p[0];
+
+ x = m0;
+ x += ( ( m0 + 2 ) & 4 ) << 1;
+ x *= ( 2 - ( m0 * x ) );
+
+ if( biL >= 16 ) x *= ( 2 - ( m0 * x ) );
+ if( biL >= 32 ) x *= ( 2 - ( m0 * x ) );
+ if( biL >= 64 ) x *= ( 2 - ( m0 * x ) );
+
+ *mm = ~x + 1;
+}
+
+/*
+ * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
+ */
+static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_int mm, const mpi *T )
+{
+ int i, n, m;
+ t_int u0, u1, *d;
+
+ memset( T->p, 0, T->n * ciL );
+
+ d = T->p;
+ n = N->n;
+ m = ( B->n < n ) ? B->n : n;
+
+ for( i = 0; i < n; i++ )
+ {
+ /*
+ * T = (T + u0*B + u1*N) / 2^biL
+ */
+ u0 = A->p[i];
+ u1 = ( d[0] + u0 * B->p[0] ) * mm;
+
+ mpi_mul_hlp( m, B->p, d, u0 );
+ mpi_mul_hlp( n, N->p, d, u1 );
+
+ *d++ = u0; d[n + 1] = 0;
+ }
+
+ memcpy( A->p, d, (n + 1) * ciL );
+
+ if( mpi_cmp_abs( A, N ) >= 0 )
+ mpi_sub_hlp( n, N->p, A->p );
+ else
+ /* prevent timing attacks */
+ mpi_sub_hlp( n, A->p, T->p );
+}
+
+/*
+ * Montgomery reduction: A = A * R^-1 mod N
+ */
+static void mpi_montred( mpi *A, const mpi *N, t_int mm, const mpi *T )
+{
+ t_int z = 1;
+ mpi U;
+
+ U.n = U.s = z;
+ U.p = &z;
+
+ mpi_montmul( A, &U, N, mm, T );
+}
+
+/*
+ * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
+ */
+int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
+{
+ int ret, i, j, wsize, wbits;
+ int bufsize, nblimbs, nbits;
+ t_int ei, mm, state;
+ mpi RR, T, W[64];
+
+ if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
+ return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+ /*
+ * Init temps and window size
+ */
+ mpi_montg_init( &mm, N );
+ mpi_init( &RR, &T, NULL );
+ memset( W, 0, sizeof( W ) );
+
+ i = mpi_msb( E );
+
+ wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
+ ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
+
+ j = N->n + 1;
+ MPI_CHK( mpi_grow( X, j ) );
+ MPI_CHK( mpi_grow( &W[1], j ) );
+ MPI_CHK( mpi_grow( &T, j * 2 ) );
+
+ /*
+ * If 1st call, pre-compute R^2 mod N
+ */
+ if( _RR == NULL || _RR->p == NULL )
+ {
+ MPI_CHK( mpi_lset( &RR, 1 ) );
+ MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
+ MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
+
+ if( _RR != NULL )
+ memcpy( _RR, &RR, sizeof( mpi ) );
+ }
+ else
+ memcpy( &RR, _RR, sizeof( mpi ) );
+
+ /*
+ * W[1] = A * R^2 * R^-1 mod N = A * R mod N
+ */
+ if( mpi_cmp_mpi( A, N ) >= 0 )
+ {
+ MPI_CHK(mpi_mod_mpi( &W[1], A, N ));
+ }
+ else
+ {
+ MPI_CHK(mpi_copy( &W[1], A ));
+ }
+
+ mpi_montmul( &W[1], &RR, N, mm, &T );
+
+ /*
+ * X = R^2 * R^-1 mod N = R mod N
+ */
+ MPI_CHK( mpi_copy( X, &RR ) );
+ mpi_montred( X, N, mm, &T );
+
+ if( wsize > 1 )
+ {
+ /*
+ * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
+ */
+ j = 1 << (wsize - 1);
+
+ MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
+ MPI_CHK( mpi_copy( &W[j], &W[1] ) );
+
+ for( i = 0; i < wsize - 1; i++ )
+ mpi_montmul( &W[j], &W[j], N, mm, &T );
+
+ /*
+ * W[i] = W[i - 1] * W[1]
+ */
+ for( i = j + 1; i < (1 << wsize); i++ )
+ {
+ MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
+ MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
+
+ mpi_montmul( &W[i], &W[1], N, mm, &T );
+ }
+ }
+
+ nblimbs = E->n;
+ bufsize = 0;
+ nbits = 0;
+ wbits = 0;
+ state = 0;
+
+ while( 1 )
+ {
+ if( bufsize == 0 )
+ {
+ if( nblimbs-- == 0 )
+ break;
+
+ bufsize = sizeof( t_int ) << 3;
+ }
+
+ bufsize--;
+
+ ei = (E->p[nblimbs] >> bufsize) & 1;
+
+ /*
+ * skip leading 0s
+ */
+ if( ei == 0 && state == 0 )
+ continue;
+
+ if( ei == 0 && state == 1 )
+ {
+ /*
+ * out of window, square X
+ */
+ mpi_montmul( X, X, N, mm, &T );
+ continue;
+ }
+
+ /*
+ * add ei to current window
+ */
+ state = 2;
+
+ nbits++;
+ wbits |= (ei << (wsize - nbits));
+
+ if( nbits == wsize )
+ {
+ /*
+ * X = X^wsize R^-1 mod N
+ */
+ for( i = 0; i < wsize; i++ )
+ mpi_montmul( X, X, N, mm, &T );
+
+ /*
+ * X = X * W[wbits] R^-1 mod N
+ */
+ mpi_montmul( X, &W[wbits], N, mm, &T );
+
+ state--;
+ nbits = 0;
+ wbits = 0;
+ }
+ }
+
+ /*
+ * process the remaining bits
+ */
+ for( i = 0; i < nbits; i++ )
+ {
+ mpi_montmul( X, X, N, mm, &T );
+
+ wbits <<= 1;
+
+ if( (wbits & (1 << wsize)) != 0 )
+ mpi_montmul( X, &W[1], N, mm, &T );
+ }
+
+ /*
+ * X = A^E * R * R^-1 mod N = A^E mod N
+ */
+ mpi_montred( X, N, mm, &T );
+
+cleanup:
+
+ for( i = (1 << (wsize - 1)); i < (1 << wsize); i++ )
+ mpi_free( &W[i], NULL );
+
+ if( _RR != NULL )
+ mpi_free( &W[1], &T, NULL );
+ else mpi_free( &W[1], &T, &RR, NULL );
+
+ return( ret );
+}
+
+/*
+ * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
+ */
+int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
+{
+ int ret, lz, lzt;
+ mpi TG, TA, TB;
+
+ mpi_init( &TG, &TA, &TB, NULL );
+
+ MPI_CHK( mpi_copy( &TA, A ) );
+ MPI_CHK( mpi_copy( &TB, B ) );
+
+ lz = mpi_lsb( &TA );
+ lzt = mpi_lsb( &TB );
+
+ if ( lzt < lz )
+ lz = lzt;
+
+ MPI_CHK( mpi_shift_r( &TA, lz ) );
+ MPI_CHK( mpi_shift_r( &TB, lz ) );
+
+ TA.s = TB.s = 1;
+
+ while( mpi_cmp_int( &TA, 0 ) != 0 )
+ {
+ MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
+ MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
+
+ if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
+ {
+ MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
+ MPI_CHK( mpi_shift_r( &TA, 1 ) );
+ }
+ else
+ {
+ MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
+ MPI_CHK( mpi_shift_r( &TB, 1 ) );
+ }
+ }
+
+ MPI_CHK( mpi_shift_l( &TB, lz ) );
+ MPI_CHK( mpi_copy( G, &TB ) );
+
+cleanup:
+
+ mpi_free( &TB, &TA, &TG, NULL );
+
+ return( ret );
+}
+
+#if defined(POLARSSL_GENPRIME)
+
+/*
+ * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
+ */
+int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
+{
+ int ret;
+ mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
+
+ if( mpi_cmp_int( N, 0 ) <= 0 )
+ return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+ mpi_init( &TA, &TU, &U1, &U2, &G,
+ &TB, &TV, &V1, &V2, NULL );
+
+ MPI_CHK( mpi_gcd( &G, A, N ) );
+
+ if( mpi_cmp_int( &G, 1 ) != 0 )
+ {
+ ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
+ goto cleanup;
+ }
+
+ MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
+ MPI_CHK( mpi_copy( &TU, &TA ) );
+ MPI_CHK( mpi_copy( &TB, N ) );
+ MPI_CHK( mpi_copy( &TV, N ) );
+
+ MPI_CHK( mpi_lset( &U1, 1 ) );
+ MPI_CHK( mpi_lset( &U2, 0 ) );
+ MPI_CHK( mpi_lset( &V1, 0 ) );
+ MPI_CHK( mpi_lset( &V2, 1 ) );
+
+ do
+ {
+ while( ( TU.p[0] & 1 ) == 0 )
+ {
+ MPI_CHK( mpi_shift_r( &TU, 1 ) );
+
+ if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
+ {
+ MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
+ MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
+ }
+
+ MPI_CHK( mpi_shift_r( &U1, 1 ) );
+ MPI_CHK( mpi_shift_r( &U2, 1 ) );
+ }
+
+ while( ( TV.p[0] & 1 ) == 0 )
+ {
+ MPI_CHK( mpi_shift_r( &TV, 1 ) );
+
+ if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
+ {
+ MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
+ MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
+ }
+
+ MPI_CHK( mpi_shift_r( &V1, 1 ) );
+ MPI_CHK( mpi_shift_r( &V2, 1 ) );
+ }
+
+ if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
+ {
+ MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
+ MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
+ MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
+ }
+ else
+ {
+ MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
+ MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
+ MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
+ }
+ }
+ while( mpi_cmp_int( &TU, 0 ) != 0 );
+
+ while( mpi_cmp_int( &V1, 0 ) < 0 )
+ MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
+
+ while( mpi_cmp_mpi( &V1, N ) >= 0 )
+ MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
+
+ MPI_CHK( mpi_copy( X, &V1 ) );
+
+cleanup:
+
+ mpi_free( &V2, &V1, &TV, &TB, &G,
+ &U2, &U1, &TU, &TA, NULL );
+
+ return( ret );
+}
+
+static const int small_prime[] =
+{
+ 3, 5, 7, 11, 13, 17, 19, 23,
+ 29, 31, 37, 41, 43, 47, 53, 59,
+ 61, 67, 71, 73, 79, 83, 89, 97,
+ 101, 103, 107, 109, 113, 127, 131, 137,
+ 139, 149, 151, 157, 163, 167, 173, 179,
+ 181, 191, 193, 197, 199, 211, 223, 227,
+ 229, 233, 239, 241, 251, 257, 263, 269,
+ 271, 277, 281, 283, 293, 307, 311, 313,
+ 317, 331, 337, 347, 349, 353, 359, 367,
+ 373, 379, 383, 389, 397, 401, 409, 419,
+ 421, 431, 433, 439, 443, 449, 457, 461,
+ 463, 467, 479, 487, 491, 499, 503, 509,
+ 521, 523, 541, 547, 557, 563, 569, 571,
+ 577, 587, 593, 599, 601, 607, 613, 617,
+ 619, 631, 641, 643, 647, 653, 659, 661,
+ 673, 677, 683, 691, 701, 709, 719, 727,
+ 733, 739, 743, 751, 757, 761, 769, 773,
+ 787, 797, 809, 811, 821, 823, 827, 829,
+ 839, 853, 857, 859, 863, 877, 881, 883,
+ 887, 907, 911, 919, 929, 937, 941, 947,
+ 953, 967, 971, 977, 983, 991, 997, -103
+};
+
+/*
+ * Miller-Rabin primality test (HAC 4.24)
+ */
+int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng )
+{
+ int ret, i, j, n, s, xs;
+ mpi W, R, T, A, RR;
+ unsigned char *p;
+
+ if( mpi_cmp_int( X, 0 ) == 0 ||
+ mpi_cmp_int( X, 1 ) == 0 )
+ return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
+
+ if( mpi_cmp_int( X, 2 ) == 0 )
+ return( 0 );
+
+ mpi_init( &W, &R, &T, &A, &RR, NULL );
+
+ xs = X->s; X->s = 1;
+
+ /*
+ * test trivial factors first
+ */
+ if( ( X->p[0] & 1 ) == 0 )
+ return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
+
+ for( i = 0; small_prime[i] > 0; i++ )
+ {
+ t_int r;
+
+ if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
+ return( 0 );
+
+ MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
+
+ if( r == 0 )
+ return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
+ }
+
+ /*
+ * W = |X| - 1
+ * R = W >> lsb( W )
+ */
+ MPI_CHK( mpi_sub_int( &W, X, 1 ) );
+ s = mpi_lsb( &W );
+ MPI_CHK( mpi_copy( &R, &W ) );
+ MPI_CHK( mpi_shift_r( &R, s ) );
+
+ i = mpi_msb( X );
+ /*
+ * HAC, table 4.4
+ */
+ n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
+ ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
+ ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
+
+ for( i = 0; i < n; i++ )
+ {
+ /*
+ * pick a random A, 1 < A < |X| - 1
+ */
+ MPI_CHK( mpi_grow( &A, X->n ) );
+
+ p = (unsigned char *) A.p;
+ for( j = 0; j < A.n * ciL; j++ )
+ *p++ = (unsigned char) f_rng( p_rng );
+
+ j = mpi_msb( &A ) - mpi_msb( &W );
+ MPI_CHK( mpi_shift_r( &A, j + 1 ) );
+ A.p[0] |= 3;
+
+ /*
+ * A = A^R mod |X|
+ */
+ MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
+
+ if( mpi_cmp_mpi( &A, &W ) == 0 ||
+ mpi_cmp_int( &A, 1 ) == 0 )
+ continue;
+
+ j = 1;
+ while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
+ {
+ /*
+ * A = A * A mod |X|
+ */
+ MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
+ MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
+
+ if( mpi_cmp_int( &A, 1 ) == 0 )
+ break;
+
+ j++;
+ }
+
+ /*
+ * not prime if A != |X| - 1 or A == 1
+ */
+ if( mpi_cmp_mpi( &A, &W ) != 0 ||
+ mpi_cmp_int( &A, 1 ) == 0 )
+ {
+ ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
+ break;
+ }
+ }
+
+cleanup:
+
+ X->s = xs;
+
+ mpi_free( &RR, &A, &T, &R, &W, NULL );
+
+ return( ret );
+}
+
+/*
+ * Prime number generation
+ */
+int mpi_gen_prime( mpi *X, int nbits, int dh_flag,
+ int (*f_rng)(void *), void *p_rng )
+{
+ int ret, k, n;
+ unsigned char *p;
+ mpi Y;
+
+ if( nbits < 3 )
+ return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+ mpi_init( &Y, NULL );
+
+ n = BITS_TO_LIMBS( nbits );
+
+ MPI_CHK( mpi_grow( X, n ) );
+ MPI_CHK( mpi_lset( X, 0 ) );
+
+ p = (unsigned char *) X->p;
+ for( k = 0; k < X->n * ciL; k++ )
+ *p++ = (unsigned char) f_rng( p_rng );
+
+ k = mpi_msb( X );
+ if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
+ if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
+
+ X->p[0] |= 3;
+
+ if( dh_flag == 0 )
+ {
+ while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
+ {
+ if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
+ goto cleanup;
+
+ MPI_CHK( mpi_add_int( X, X, 2 ) );
+ }
+ }
+ else
+ {
+ MPI_CHK( mpi_sub_int( &Y, X, 1 ) );
+ MPI_CHK( mpi_shift_r( &Y, 1 ) );
+
+ while( 1 )
+ {
+ if( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) == 0 )
+ {
+ if( ( ret = mpi_is_prime( &Y, f_rng, p_rng ) ) == 0 )
+ break;
+
+ if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
+ goto cleanup;
+ }
+
+ if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
+ goto cleanup;
+
+ MPI_CHK( mpi_add_int( &Y, X, 1 ) );
+ MPI_CHK( mpi_add_int( X, X, 2 ) );
+ MPI_CHK( mpi_shift_r( &Y, 1 ) );
+ }
+ }
+
+cleanup:
+
+ mpi_free( &Y, NULL );
+
+ return( ret );
+}
+
+#endif
+
+#if defined(POLARSSL_SELF_TEST)
+
+#define GCD_PAIR_COUNT 3
+
+static const int gcd_pairs[GCD_PAIR_COUNT][3] =
+{
+ { 693, 609, 21 },
+ { 1764, 868, 28 },
+ { 768454923, 542167814, 1 }
+};
+
+/*
+ * Checkup routine
+ */
+int mpi_self_test( int verbose )
+{
+ int ret, i;
+ mpi A, E, N, X, Y, U, V;
+
+ mpi_init( &A, &E, &N, &X, &Y, &U, &V, NULL );
+
+ MPI_CHK( mpi_read_string( &A, 16,
+ "EFE021C2645FD1DC586E69184AF4A31E" \
+ "D5F53E93B5F123FA41680867BA110131" \
+ "944FE7952E2517337780CB0DB80E61AA" \
+ "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
+
+ MPI_CHK( mpi_read_string( &E, 16,
+ "B2E7EFD37075B9F03FF989C7C5051C20" \
+ "34D2A323810251127E7BF8625A4F49A5" \
+ "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
+ "5B5C25763222FEFCCFC38B832366C29E" ) );
+
+ MPI_CHK( mpi_read_string( &N, 16,
+ "0066A198186C18C10B2F5ED9B522752A" \
+ "9830B69916E535C8F047518A889A43A5" \
+ "94B6BED27A168D31D4A52F88925AA8F5" ) );
+
+ MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
+
+ MPI_CHK( mpi_read_string( &U, 16,
+ "602AB7ECA597A3D6B56FF9829A5E8B85" \
+ "9E857EA95A03512E2BAE7391688D264A" \
+ "A5663B0341DB9CCFD2C4C5F421FEC814" \
+ "8001B72E848A38CAE1C65F78E56ABDEF" \
+ "E12D3C039B8A02D6BE593F0BBBDA56F1" \
+ "ECF677152EF804370C1A305CAF3B5BF1" \
+ "30879B56C61DE584A0F53A2447A51E" ) );
+
+ if( verbose != 0 )
+ printf( " MPI test #1 (mul_mpi): " );
+
+ if( mpi_cmp_mpi( &X, &U ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+
+ MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
+
+ MPI_CHK( mpi_read_string( &U, 16,
+ "256567336059E52CAE22925474705F39A94" ) );
+
+ MPI_CHK( mpi_read_string( &V, 16,
+ "6613F26162223DF488E9CD48CC132C7A" \
+ "0AC93C701B001B092E4E5B9F73BCD27B" \
+ "9EE50D0657C77F374E903CDFA4C642" ) );
+
+ if( verbose != 0 )
+ printf( " MPI test #2 (div_mpi): " );
+
+ if( mpi_cmp_mpi( &X, &U ) != 0 ||
+ mpi_cmp_mpi( &Y, &V ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+
+ MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
+
+ MPI_CHK( mpi_read_string( &U, 16,
+ "36E139AEA55215609D2816998ED020BB" \
+ "BD96C37890F65171D948E9BC7CBAA4D9" \
+ "325D24D6A3C12710F10A09FA08AB87" ) );
+
+ if( verbose != 0 )
+ printf( " MPI test #3 (exp_mod): " );
+
+ if( mpi_cmp_mpi( &X, &U ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+
+ MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
+
+ MPI_CHK( mpi_read_string( &U, 16,
+ "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
+ "C3DBA76456363A10869622EAC2DD84EC" \
+ "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
+
+ if( verbose != 0 )
+ printf( " MPI test #4 (inv_mod): " );
+
+ if( mpi_cmp_mpi( &X, &U ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+
+ if( verbose != 0 )
+ printf( " MPI test #5 (simple gcd): " );
+
+ for ( i = 0; i < GCD_PAIR_COUNT; i++)
+ {
+ MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
+ MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
+
+ MPI_CHK( mpi_gcd( &A, &X, &Y ) );
+
+ if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed at %d\n", i );
+
+ return( 1 );
+ }
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+
+cleanup:
+
+ if( ret != 0 && verbose != 0 )
+ printf( "Unexpected error, return code = %08X\n", ret );
+
+ mpi_free( &V, &U, &Y, &X, &N, &E, &A, NULL );
+
+ if( verbose != 0 )
+ printf( "\n" );
+
+ return( ret );
+}
+
+#endif
+
+#endif
diff --git a/ap/app/zte_comm/zte_locknet/src/zctrm_ln_md5.c b/ap/app/zte_comm/zte_locknet/src/zctrm_ln_md5.c
new file mode 100755
index 0000000..68143dd
--- /dev/null
+++ b/ap/app/zte_comm/zte_locknet/src/zctrm_ln_md5.c
@@ -0,0 +1,306 @@
+/*
+ ***********************************************************************
+ ** md5.c -- the source code for MD5 routines **
+ ** RSA Data Security, Inc. MD5 Message-Digest Algorithm **
+ ** Created: 2/17/90 RLR **
+ ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **
+ ***********************************************************************
+ */
+
+/*
+ ***********************************************************************
+ ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
+ ** **
+ ** License to copy and use this software is granted provided that **
+ ** it is identified as the "RSA Data Security, Inc. MD5 Message- **
+ ** Digest Algorithm" in all material mentioning or referencing this **
+ ** software or this function. **
+ ** **
+ ** License is also granted to make and use derivative works **
+ ** provided that such works are identified as "derived from the RSA **
+ ** Data Security, Inc. MD5 Message-Digest Algorithm" in all **
+ ** material mentioning or referencing the derived work. **
+ ** **
+ ** RSA Data Security, Inc. makes no representations concerning **
+ ** either the merchantability of this software or the suitability **
+ ** of this software for any particular purpose. It is provided "as **
+ ** is" without express or implied warranty of any kind. **
+ ** **
+ ** These notices must be retained in any copies of any part of this **
+ ** documentation and/or software. **
+ ***********************************************************************
+ */
+
+
+#include "zctrm_ln_md5.h"
+#include <string.h>
+
+/*
+ ***********************************************************************
+ ** Message-digest routines: **
+ ** To form the message digest for a message M **
+ ** (1) Initialize a context buffer ctx using md5_init **
+ ** (2) Call md5_update on ctx and M **
+ ** (3) Call md5_final on ctx **
+ ** The message digest is now in ctx->digest[0...15] **
+ ***********************************************************************
+ */
+
+/* forward declaration */
+static void transform(u32_t *buf, u32_t *in);
+
+static unsigned char PADDING[64] = {
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* F, G, H and I are basic MD5 functions */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
+/* Rotation is separate from addition to prevent recomputation */
+#define FF(a, b, c, d, x, s, ac) \
+ {(a) += F ((b), (c), (d)) + (x) + (u32_t)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define GG(a, b, c, d, x, s, ac) \
+ {(a) += G ((b), (c), (d)) + (x) + (u32_t)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define HH(a, b, c, d, x, s, ac) \
+ {(a) += H ((b), (c), (d)) + (x) + (u32_t)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define II(a, b, c, d, x, s, ac) \
+ {(a) += I ((b), (c), (d)) + (x) + (u32_t)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+
+#ifdef __STDC__
+#define UL(x) x##UL
+#else
+#ifdef WIN32
+#define UL(x) x##UL
+#else
+#define UL(x) x
+#endif
+#endif
+
+/* The routine md5_init initializes the message-digest context
+ mdContext. All fields are set to zero.
+ */
+void
+md5_init(md5_ctx *ctx)
+{
+ ctx->i[0] = ctx->i[1] = (u32_t)0;
+
+ /* Load magic initialization constants. */
+ ctx->buf[0] = (u32_t)0x67452301UL;
+ ctx->buf[1] = (u32_t)0xefcdab89UL;
+ ctx->buf[2] = (u32_t)0x98badcfeUL;
+ ctx->buf[3] = (u32_t)0x10325476UL;
+}
+
+/* The routine md5_update updates the message-digest context to
+ account for the presence of each of the characters buf[0..inLen-1]
+ in the message whose digest is being computed.
+ */
+void
+md5_update(md5_ctx *ctx, unsigned char *buf, unsigned int len)
+{
+ u32_t in[16];
+ int mdi;
+ unsigned int i, ii;
+
+#if 0
+ ppp_trace(LOG_INFO, "MD5Update: %u:%.*H\n", len, MIN(len, 20) * 2, buf);
+ ppp_trace(LOG_INFO, "MD5Update: %u:%s\n", len, buf);
+#endif
+
+ /* compute number of bytes mod 64 */
+ mdi = (int)((ctx->i[0] >> 3) & 0x3F);
+
+ /* update number of bits */
+ if ((ctx->i[0] + ((u32_t)len << 3)) < ctx->i[0]) {
+ ctx->i[1]++;
+ }
+ ctx->i[0] += ((u32_t)len << 3);
+ ctx->i[1] += ((u32_t)len >> 29);
+
+ while (len--) {
+ /* add new character to buffer, increment mdi */
+ ctx->in[mdi++] = *buf++;
+
+ /* transform if necessary */
+ if (mdi == 0x40) {
+ for (i = 0, ii = 0; i < 16; i++, ii += 4) {
+ in[i] = (((u32_t)ctx->in[ii+3]) << 24) |
+ (((u32_t)ctx->in[ii+2]) << 16) |
+ (((u32_t)ctx->in[ii+1]) << 8) |
+ ((u32_t)ctx->in[ii]);
+ }
+ transform (ctx->buf, in);
+ mdi = 0;
+ }
+ }
+}
+
+/* The routine md5_final terminates the message-digest computation and
+ ends with the desired message digest in ctx->digest[0...15].
+ */
+void md5_final(unsigned char hash[], md5_ctx *ctx)
+{
+ u32_t in[16];
+ int mdi;
+ unsigned int i, ii;
+ unsigned int pad_len;
+
+ /* save number of bits */
+ in[14] = ctx->i[0];
+ in[15] = ctx->i[1];
+
+ /* compute number of bytes mod 64 */
+ mdi = (int)((ctx->i[0] >> 3) & 0x3F);
+
+ /* pad out to 56 mod 64 */
+ pad_len = (mdi < 56) ? (56 - mdi) : (120 - mdi);
+ md5_update (ctx, PADDING, pad_len);
+
+ /* append length in bits and transform */
+ for (i = 0, ii = 0; i < 14; i++, ii += 4) {
+ in[i] = (((u32_t)ctx->in[ii+3]) << 24) |
+ (((u32_t)ctx->in[ii+2]) << 16) |
+ (((u32_t)ctx->in[ii+1]) << 8) |
+ ((u32_t)ctx->in[ii]);
+ }
+ transform (ctx->buf, in);
+
+ /* store buffer in digest */
+ for (i = 0, ii = 0; i < 4; i++, ii += 4) {
+ ctx->digest[ii] = (unsigned char)(ctx->buf[i] & 0xFF);
+ ctx->digest[ii+1] =
+ (unsigned char)((ctx->buf[i] >> 8) & 0xFF);
+ ctx->digest[ii+2] =
+ (unsigned char)((ctx->buf[i] >> 16) & 0xFF);
+ ctx->digest[ii+3] =
+ (unsigned char)((ctx->buf[i] >> 24) & 0xFF);
+ }
+ SMEMCPY(hash, ctx->digest, 16);
+}
+
+/* Basic MD5 step. Transforms buf based on in.
+ */
+static void
+transform (u32_t *buf, u32_t *in)
+{
+ u32_t a = buf[0], b = buf[1], c = buf[2], d = buf[3];
+
+ /* Round 1 */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+ FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */
+ FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */
+ FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */
+ FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */
+ FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */
+ FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */
+ FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */
+ FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */
+ FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */
+ FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */
+ FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */
+ FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */
+ FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */
+ FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */
+ FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */
+ FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */
+
+ /* Round 2 */
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+ GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */
+ GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */
+ GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */
+ GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */
+ GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */
+ GG ( d, a, b, c, in[10], S22, UL( 38016083)); /* 22 */
+ GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */
+ GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */
+ GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */
+ GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */
+ GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */
+ GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */
+ GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */
+ GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */
+ GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */
+ GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */
+
+ /* Round 3 */
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+ HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */
+ HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */
+ HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */
+ HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */
+ HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */
+ HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */
+ HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */
+ HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */
+ HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */
+ HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */
+ HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */
+ HH ( b, c, d, a, in[ 6], S34, UL( 76029189)); /* 44 */
+ HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */
+ HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */
+ HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */
+ HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */
+
+ /* Round 4 */
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+ II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */
+ II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */
+ II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */
+ II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */
+ II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */
+ II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */
+ II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */
+ II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */
+ II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */
+ II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */
+ II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */
+ II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */
+ II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */
+ II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */
+ II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */
+ II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
diff --git a/ap/app/zte_comm/zte_locknet/src/zctrm_ln_rsa.c b/ap/app/zte_comm/zte_locknet/src/zctrm_ln_rsa.c
new file mode 100755
index 0000000..5cd1f5c
--- /dev/null
+++ b/ap/app/zte_comm/zte_locknet/src/zctrm_ln_rsa.c
@@ -0,0 +1,742 @@
+/*
+ * The RSA public-key cryptosystem
+ *
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+/*
+ * RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
+ *
+ * http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
+ * http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
+ */
+
+#include "zctrm_ln_config.h"
+
+#if defined(POLARSSL_RSA_C)
+
+#include "zctrm_ln_rsa.h"
+
+//#include <stdlib.h>
+//#include <string.h>
+//#include <stdio.h>
+
+/*
+ * Initialize an RSA context
+ */
+void rsa_init( rsa_context *ctx,
+ int padding,
+ int hash_id )
+{
+ memset( ctx, 0, sizeof( rsa_context ) );
+
+ ctx->padding = padding;
+ ctx->hash_id = hash_id;
+}
+
+#if defined(POLARSSL_GENPRIME)
+
+/*
+ * Generate an RSA keypair
+ */
+int rsa_gen_key( rsa_context *ctx,
+ int (*f_rng)(void *),
+ void *p_rng,
+ int nbits, int exponent )
+{
+ int ret;
+ mpi P1, Q1, H, G;
+
+ if( f_rng == NULL || nbits < 128 || exponent < 3 )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ mpi_init( &P1, &Q1, &H, &G, NULL );
+
+ /*
+ * find primes P and Q with Q < P so that:
+ * GCD( E, (P-1)*(Q-1) ) == 1
+ */
+ MPI_CHK( mpi_lset( &ctx->E, exponent ) );
+
+ do
+ {
+ MPI_CHK( mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0,
+ f_rng, p_rng ) );
+
+ MPI_CHK( mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0,
+ f_rng, p_rng ) );
+
+ if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
+ mpi_swap( &ctx->P, &ctx->Q );
+
+ if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
+ continue;
+
+ MPI_CHK( mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
+ if( mpi_msb( &ctx->N ) != nbits )
+ continue;
+
+ MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
+ MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
+ MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
+ MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
+ }
+ while( mpi_cmp_int( &G, 1 ) != 0 );
+
+ /*
+ * D = E^-1 mod ((P-1)*(Q-1))
+ * DP = D mod (P - 1)
+ * DQ = D mod (Q - 1)
+ * QP = Q^-1 mod P
+ */
+ MPI_CHK( mpi_inv_mod( &ctx->D , &ctx->E, &H ) );
+ MPI_CHK( mpi_mod_mpi( &ctx->DP, &ctx->D, &P1 ) );
+ MPI_CHK( mpi_mod_mpi( &ctx->DQ, &ctx->D, &Q1 ) );
+ MPI_CHK( mpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) );
+
+ ctx->len = ( mpi_msb( &ctx->N ) + 7 ) >> 3;
+
+cleanup:
+
+ mpi_free( &G, &H, &Q1, &P1, NULL );
+
+ if( ret != 0 )
+ {
+ rsa_free( ctx );
+ return( POLARSSL_ERR_RSA_KEY_GEN_FAILED | ret );
+ }
+
+ return( 0 );
+}
+
+#endif
+
+/*
+ * Check a public RSA key
+ */
+int rsa_check_pubkey( const rsa_context *ctx )
+{
+ if( !ctx->N.p || !ctx->E.p )
+ return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
+
+ if( ( ctx->N.p[0] & 1 ) == 0 ||
+ ( ctx->E.p[0] & 1 ) == 0 )
+ return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
+
+ if( mpi_msb( &ctx->N ) < 128 ||
+ mpi_msb( &ctx->N ) > 4096 )
+ return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
+
+ if( mpi_msb( &ctx->E ) < 2 ||
+ mpi_msb( &ctx->E ) > 64 )
+ return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
+
+ return( 0 );
+}
+
+/*
+ * Check a private RSA key
+ */
+int rsa_check_privkey( const rsa_context *ctx )
+{
+ int ret;
+ mpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2;
+
+ if( ( ret = rsa_check_pubkey( ctx ) ) != 0 )
+ return( ret );
+
+ if( !ctx->P.p || !ctx->Q.p || !ctx->D.p )
+ return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
+
+ mpi_init( &PQ, &DE, &P1, &Q1, &H, &I, &G, &G2, &L1, &L2, NULL );
+
+ MPI_CHK( mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) );
+ MPI_CHK( mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) );
+ MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
+ MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
+ MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
+ MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
+
+ MPI_CHK( mpi_gcd( &G2, &P1, &Q1 ) );
+ MPI_CHK( mpi_div_mpi( &L1, &L2, &H, &G2 ) );
+ MPI_CHK( mpi_mod_mpi( &I, &DE, &L1 ) );
+
+ /*
+ * Check for a valid PKCS1v2 private key
+ */
+ if( mpi_cmp_mpi( &PQ, &ctx->N ) == 0 &&
+ mpi_cmp_int( &L2, 0 ) == 0 &&
+ mpi_cmp_int( &I, 1 ) == 0 &&
+ mpi_cmp_int( &G, 1 ) == 0 )
+ {
+ mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, &G2, &L1, &L2, NULL );
+ return( 0 );
+ }
+
+
+cleanup:
+
+ mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, &G2, &L1, &L2, NULL );
+ return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED | ret );
+}
+
+/*
+ * Do an RSA public key operation
+ */
+int rsa_public( rsa_context *ctx,
+ const unsigned char *input,
+ unsigned char *output )
+{
+ int ret, olen;
+ mpi T;
+
+ mpi_init( &T, NULL );
+
+ MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
+
+ if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
+ {
+ mpi_free( &T, NULL );
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+ }
+
+ olen = ctx->len;
+ MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
+ MPI_CHK( mpi_write_binary( &T, output, olen ) );
+
+cleanup:
+
+ mpi_free( &T, NULL );
+
+ if( ret != 0 )
+ return( POLARSSL_ERR_RSA_PUBLIC_FAILED | ret );
+
+ return( 0 );
+}
+
+/*
+ * Do an RSA private key operation
+ */
+int rsa_private( rsa_context *ctx,
+ const unsigned char *input,
+ unsigned char *output )
+{
+ int ret, olen;
+ mpi T, T1, T2;
+
+ mpi_init( &T, &T1, &T2, NULL );
+
+ MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
+
+ if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
+ {
+ mpi_free( &T, NULL );
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+ }
+
+#if 0
+ MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
+#else
+ /*
+ * faster decryption using the CRT
+ *
+ * T1 = input ^ dP mod P
+ * T2 = input ^ dQ mod Q
+ */
+ MPI_CHK( mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) );
+ MPI_CHK( mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) );
+
+ /*
+ * T = (T1 - T2) * (Q^-1 mod P) mod P
+ */
+ MPI_CHK( mpi_sub_mpi( &T, &T1, &T2 ) );
+ MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->QP ) );
+ MPI_CHK( mpi_mod_mpi( &T, &T1, &ctx->P ) );
+
+ /*
+ * output = T2 + T * Q
+ */
+ MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->Q ) );
+ MPI_CHK( mpi_add_mpi( &T, &T2, &T1 ) );
+#endif
+
+ olen = ctx->len;
+ MPI_CHK( mpi_write_binary( &T, output, olen ) );
+
+cleanup:
+
+ mpi_free( &T, &T1, &T2, NULL );
+
+ if( ret != 0 )
+ return( POLARSSL_ERR_RSA_PRIVATE_FAILED | ret );
+
+ return( 0 );
+}
+
+/*
+ * Add the message padding, then do an RSA operation
+ */
+int rsa_pkcs1_encrypt( rsa_context *ctx,
+ int (*f_rng)(void *),
+ void *p_rng,
+ int mode, int ilen,
+ const unsigned char *input,
+ unsigned char *output )
+{
+ int nb_pad, olen;
+ unsigned char *p = output;
+
+ olen = ctx->len;
+
+ switch( ctx->padding )
+ {
+ case RSA_PKCS_V15:
+
+ if( ilen < 0 || olen < ilen + 11 || f_rng == NULL )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ nb_pad = olen - 3 - ilen;
+
+ *p++ = 0;
+ *p++ = RSA_CRYPT;
+
+ while( nb_pad-- > 0 )
+ {
+ int rng_dl = 100;
+
+ do {
+ *p = (unsigned char) f_rng( p_rng );
+ } while( *p == 0 && --rng_dl );
+
+ // Check if RNG failed to generate data
+ //
+ if( rng_dl == 0 )
+ return POLARSSL_ERR_RSA_RNG_FAILED;
+
+ p++;
+ }
+ *p++ = 0;
+ memcpy( p, input, ilen );
+ break;
+
+ default:
+
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ }
+
+ return( ( mode == RSA_PUBLIC )
+ ? rsa_public( ctx, output, output )
+ : rsa_private( ctx, output, output ) );
+}
+
+/*
+ * Do an RSA operation, then remove the message padding
+ */
+int rsa_pkcs1_decrypt( rsa_context *ctx,
+ int mode, int *olen,
+ const unsigned char *input,
+ unsigned char *output,
+ int output_max_len)
+{
+ int ret, ilen;
+ unsigned char *p;
+ unsigned char buf[1024];
+
+ ilen = ctx->len;
+
+ if( ilen < 16 || ilen > (int) sizeof( buf ) )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ ret = ( mode == RSA_PUBLIC )
+ ? rsa_public( ctx, input, buf )
+ : rsa_private( ctx, input, buf );
+
+ if( ret != 0 )
+ return( ret );
+
+ p = buf;
+
+ switch( ctx->padding )
+ {
+ case RSA_PKCS_V15:
+
+ if( *p++ != 0 || *p++ != RSA_CRYPT )
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+
+ while( *p != 0 )
+ {
+ if( p >= buf + ilen - 1 )
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ p++;
+ }
+ p++;
+ break;
+
+ default:
+
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ }
+
+ if (ilen - (int)(p - buf) > output_max_len)
+ return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );
+
+ *olen = ilen - (int)(p - buf);
+ memcpy( output, p, *olen );
+
+ return( 0 );
+}
+
+/*
+ * Do an RSA operation to sign the message digest
+ */
+int rsa_pkcs1_sign( rsa_context *ctx,
+ int mode,
+ int hash_id,
+ int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig )
+{
+ int nb_pad, olen;
+ unsigned char *p = sig;
+
+ olen = ctx->len;
+
+ switch( ctx->padding )
+ {
+ case RSA_PKCS_V15:
+
+ switch( hash_id )
+ {
+ case SIG_RSA_RAW:
+ nb_pad = olen - 3 - hashlen;
+ break;
+
+ case SIG_RSA_MD2:
+ case SIG_RSA_MD4:
+ case SIG_RSA_MD5:
+ nb_pad = olen - 3 - 34;
+ break;
+
+ case SIG_RSA_SHA1:
+ nb_pad = olen - 3 - 35;
+ break;
+
+ case SIG_RSA_SHA224:
+ nb_pad = olen - 3 - 47;
+ break;
+
+ case SIG_RSA_SHA256:
+ nb_pad = olen - 3 - 51;
+ break;
+
+ case SIG_RSA_SHA384:
+ nb_pad = olen - 3 - 67;
+ break;
+
+ case SIG_RSA_SHA512:
+ nb_pad = olen - 3 - 83;
+ break;
+
+
+ default:
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+ }
+
+ if( nb_pad < 8 )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ *p++ = 0;
+ *p++ = RSA_SIGN;
+ memset( p, 0xFF, nb_pad );
+ p += nb_pad;
+ *p++ = 0;
+ break;
+
+ default:
+
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ }
+
+ switch( hash_id )
+ {
+ case SIG_RSA_RAW:
+ memcpy( p, hash, hashlen );
+ break;
+
+ case SIG_RSA_MD2:
+ memcpy( p, ASN1_HASH_MDX, 18 );
+ memcpy( p + 18, hash, 16 );
+ p[13] = 2; break;
+
+ case SIG_RSA_MD4:
+ memcpy( p, ASN1_HASH_MDX, 18 );
+ memcpy( p + 18, hash, 16 );
+ p[13] = 4; break;
+
+ case SIG_RSA_MD5:
+ memcpy( p, ASN1_HASH_MDX, 18 );
+ memcpy( p + 18, hash, 16 );
+ p[13] = 5; break;
+
+ case SIG_RSA_SHA1:
+ memcpy( p, ASN1_HASH_SHA1, 15 );
+ memcpy( p + 15, hash, 20 );
+ break;
+
+ case SIG_RSA_SHA224:
+ memcpy( p, ASN1_HASH_SHA2X, 19 );
+ memcpy( p + 19, hash, 28 );
+ p[1] += 28; p[14] = 4; p[18] += 28; break;
+
+ case SIG_RSA_SHA256:
+ memcpy( p, ASN1_HASH_SHA2X, 19 );
+ memcpy( p + 19, hash, 32 );
+ p[1] += 32; p[14] = 1; p[18] += 32; break;
+
+ case SIG_RSA_SHA384:
+ memcpy( p, ASN1_HASH_SHA2X, 19 );
+ memcpy( p + 19, hash, 48 );
+ p[1] += 48; p[14] = 2; p[18] += 48; break;
+
+ case SIG_RSA_SHA512:
+ memcpy( p, ASN1_HASH_SHA2X, 19 );
+ memcpy( p + 19, hash, 64 );
+ p[1] += 64; p[14] = 3; p[18] += 64; break;
+
+ default:
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+ }
+
+ return( ( mode == RSA_PUBLIC )
+ ? rsa_public( ctx, sig, sig )
+ : rsa_private( ctx, sig, sig ) );
+}
+
+/*
+ * Do an RSA operation and check the message digest
+ */
+int rsa_pkcs1_verify( rsa_context *ctx,
+ int mode,
+ int hash_id,
+ int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig )
+{
+ int ret, len, siglen;
+ unsigned char *p, c;
+ unsigned char buf[1024];
+
+ siglen = ctx->len;
+
+ if( siglen < 16 || siglen > (int) sizeof( buf ) )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ ret = ( mode == RSA_PUBLIC )
+ ? rsa_public( ctx, sig, buf )
+ : rsa_private( ctx, sig, buf );
+
+ if( ret != 0 )
+ return( ret );
+
+ p = buf;
+
+ switch( ctx->padding )
+ {
+ case RSA_PKCS_V15:
+
+ if( *p++ != 0 || *p++ != RSA_SIGN )
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+
+ while( *p != 0 )
+ {
+ if( p >= buf + siglen - 1 || *p != 0xFF )
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ p++;
+ }
+ p++;
+ break;
+
+ default:
+
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ }
+
+ len = siglen - (int)( p - buf );
+
+ if( len == 34 )
+ {
+ c = p[13];
+ p[13] = 0;
+
+ if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+ if( ( c == 2 && hash_id == SIG_RSA_MD2 ) ||
+ ( c == 4 && hash_id == SIG_RSA_MD4 ) ||
+ ( c == 5 && hash_id == SIG_RSA_MD5 ) )
+ {
+ if( memcmp( p + 18, hash, 16 ) == 0 )
+ return( 0 );
+ else
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+ }
+ }
+
+ if( len == 35 && hash_id == SIG_RSA_SHA1 )
+ {
+ if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
+ memcmp( p + 15, hash, 20 ) == 0 )
+ return( 0 );
+ else
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+ }
+ if( ( len == 19 + 28 && p[14] == 4 && hash_id == SIG_RSA_SHA224 ) ||
+ ( len == 19 + 32 && p[14] == 1 && hash_id == SIG_RSA_SHA256 ) ||
+ ( len == 19 + 48 && p[14] == 2 && hash_id == SIG_RSA_SHA384 ) ||
+ ( len == 19 + 64 && p[14] == 3 && hash_id == SIG_RSA_SHA512 ) )
+ {
+ c = p[1] - 17;
+ p[1] = 17;
+ p[14] = 0;
+
+ if( p[18] == c &&
+ memcmp( p, ASN1_HASH_SHA2X, 18 ) == 0 &&
+ memcmp( p + 19, hash, c ) == 0 )
+ return( 0 );
+ else
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+ }
+
+ if( len == hashlen && hash_id == SIG_RSA_RAW )
+ {
+ if( memcmp( p, hash, hashlen ) == 0 )
+ return( 0 );
+ else
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+ }
+
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+}
+
+/*
+ * Free the components of an RSA key
+ */
+void rsa_free( rsa_context *ctx )
+{
+ mpi_free( &ctx->RQ, &ctx->RP, &ctx->RN,
+ &ctx->QP, &ctx->DQ, &ctx->DP,
+ &ctx->Q, &ctx->P, &ctx->D,
+ &ctx->E, &ctx->N, NULL );
+}
+
+
+int myrand( void *rng_state )
+{
+ if( rng_state != NULL )
+ rng_state = NULL;
+
+ return( rand() );
+}
+
+//RSA-1024
+#define KEY_LEN 128
+
+#define RSA_N "7AD4B6862361FC78613274E368AB8997" \
+ "E3D8D0268176624F8CBD466B2FA9BF76" \
+ "541C86E8F759C9EA3D1250FDB50575DD" \
+ "3562F567667C96866D8C0887AC70D05C" \
+ "E40D87A918CA6511F5FD224FC90F51CF" \
+ "A481BF3A4813D22A96FE8B36515314C0" \
+ "A044CA60D04BA1381E475029FF62F352" \
+ "8CDC407292AD7CB02BF9F89E2E0B02CB"
+
+#define RSA_E "65537"
+
+#define RSA_D "23F9950763921D30C0F10290527978D2" \
+ "7786CCDAB46CD564FD8B9AD4C3F82DF8" \
+ "BD2B5A047466325D39D1B33F7C8C53A2" \
+ "C8EA375F8492FA71933979E5F3295728" \
+ "7F6C5D73DFDA92FE287EBA0408D0D264" \
+ "D4C32D91A1BE7A89F6F06F30EF1B2083" \
+ "F26AE55BE46E26279CDE13C5DC3F945C" \
+ "D593D5C359541271FEB1F588E1F023CF"
+
+#define RSA_P "B81B60220C9C6B930E32AA8A5BA31683" \
+ "DAF23E20667D9260BA53F31D9CD979CA" \
+ "4B9F856C2C7F09D7B2F6162C8DC5A592" \
+ "16C9A833F81953792260A688EB7C3F1D"
+
+#define RSA_Q "AACBC13F7CDC6DE0BEED53AF68CF69D5" \
+ "7ED27BDF36DD74F7E6CFF06632180648" \
+ "759251906FA33F3E2F979CDD41396042" \
+ "1AB3B781C3A65032C38BE9E4514B1D07"
+
+#define RSA_DP "13AD57D729F248656D49B206C5C5D90A" \
+ "350907A004DADCA94BA56ADEEB2F6E02" \
+ "45295128ED2F125CF125A76E94A5698E" \
+ "D10AD5471CFE8906838BD64BA6AA041F"
+
+#define RSA_DQ "43F654E13885AB914A4F74FE5D2A43D2" \
+ "47ADC44C52F8B958EE3EDD972C4CF513" \
+ "83F9CB230A1AACE73CC4C53DD935D141" \
+ "7FF2E997C933DE9789791160FF3860F5"
+
+#define RSA_QP "6CB241916FAFC385CAC87F04F4FCDADA" \
+ "1584AF749F42F2FF239C9F32B6430FCC" \
+ "81CAD12196897BDFB40E2CD6FC968DA7" \
+ "C5672E607BE70159D933A0EFB2D034BA"
+
+int rsa_private_decrypt(const unsigned char *rsa_ciphertext, unsigned char *rsa_decrypted)
+{
+ rsa_context rsa;
+
+ rsa_init( &rsa, RSA_PKCS_V15, 0 );
+
+ rsa.len = KEY_LEN;
+ mpi_read_string( &rsa.N , 16, RSA_N );
+ mpi_read_string( &rsa.E , 16, RSA_E );
+ mpi_read_string( &rsa.D , 16, RSA_D );
+ mpi_read_string( &rsa.P , 16, RSA_P );
+ mpi_read_string( &rsa.Q , 16, RSA_Q );
+ mpi_read_string( &rsa.DP, 16, RSA_DP );
+ mpi_read_string( &rsa.DQ, 16, RSA_DQ );
+ mpi_read_string( &rsa.QP, 16, RSA_QP );
+
+ if( rsa_check_pubkey( &rsa ) != 0 ||
+ rsa_check_privkey( &rsa ) != 0 )
+ {
+ at_print(AT_DEBUG, "rsa_check failed\n" );
+ return -1;
+ }
+
+ if( rsa_private(&rsa, rsa_ciphertext, rsa_decrypted) != 0 )
+ {
+ at_print(AT_DEBUG,"rsa_private failed\n" );
+ return -1;
+ }
+
+ rsa_free( &rsa );
+
+ at_print(AT_DEBUG,"decrypt passed\n\n" );
+ return 0;
+}
+
+#endif
diff --git a/ap/app/zte_comm/zte_locknet/src/zctrm_locknet_main.c b/ap/app/zte_comm/zte_locknet/src/zctrm_locknet_main.c
new file mode 100755
index 0000000..ed4968f
--- /dev/null
+++ b/ap/app/zte_comm/zte_locknet/src/zctrm_locknet_main.c
@@ -0,0 +1,90 @@
+#include <stdio.h>
+#include <unistd.h>
+#include "zctrm_locknet.h"
+
+int sendflag = 0;
+void locknet_msg_proc(MSG_BUF *msg_buf)
+{
+ switch (msg_buf->usMsgCmd) {
+ case MSG_CMD_LOCKLISTAUTH_REQ:
+ zCtrm_LocknetAuthProc(msg_buf);
+ break;
+
+ case MSG_CMD_LOCKNETLIST_SET_REQ:
+ zCtrm_LocknetListSet(msg_buf);
+ break;
+
+ case MSG_CMD_LOCKNETKEY_REQ:
+ zCtrm_LocknetKeyProc(msg_buf);
+ break;
+
+ case MSG_CMD_LOCKNETAMTSTATUS_GET_REQ:
+ zCtrm_LocknetAmtStatus(msg_buf);
+ break;
+
+ case MSG_CMD_LOCKNETDIGEST_GET_REQ:
+ zCtrm_LocknetDigestGet(msg_buf);
+ break;
+
+ case MSG_CMD_LOCKNETSIGN_SET_REQ:
+ zCtrm_LocknetSignSet(msg_buf);
+ break;
+
+ case MSG_CMD_LOCKNETLEVEL_GET_REQ:
+ zCtrm_LocknetLevel(msg_buf);
+ break;
+
+ case MSG_CMD_LOCKNETLIST_GET_REQ:
+ zCtrm_LocknetListGetProc(msg_buf);
+ break;
+
+ case MSG_CMD_LOCKNETAUTH_REQ:
+ sendflag = 1;
+ zCtrm_makeLocknetAuth(msg_buf);
+ break;
+
+ case MSG_CMD_LOCKNETUNLOCKTIMES_GET_REQ:
+ zCtrm_LocknetUnlockTimes(msg_buf);
+ break;
+
+ case MSG_CMD_LOCKNETSTATUS_GET_REQ:
+ zCtrm_LocknetStatus(msg_buf);
+ break;
+
+ case MSG_CMD_LOCKNETUNLOCK_REQ:
+ zCtrm_LocknetUnlock(msg_buf);
+ break;
+ case MSG_CMD_ZURDY_LOCKAUTH_REQ:
+ zCtrm_makeLocknetAuth(msg_buf);
+ break;
+ default:
+ break;
+ }
+}
+
+int zte_locknet_main(int argc, char* argv[])
+{
+ int msg_handle = 0;
+ MSG_BUF msg;
+ LONG msg_size = sizeof(MSG_BUF)-sizeof(LONG);
+ prctl(PR_SET_NAME, "locknet", 0, 0, 0);
+ /* ´´½¨ÏûÏ¢¶ÓÁÐ*/
+ msg_handle = msgget(MODULE_ID_LOCKNET, IPC_CREAT|0600);
+ while(1)
+ {
+ memset(&msg, 0x00, sizeof(MSG_BUF));
+
+ /* »ñÈ¡ÏûÏ¢¶ÓÁÐÏûÏ¢²¢´¦Àí*/
+ if (msgrcv(msg_handle, &msg, msg_size, 0, 0) >= 0)
+ {
+ locknet_msg_proc(&msg);
+ }
+ else
+ {
+ if(errno != EINTR)
+ slog(AT_PRINT,SLOG_ERR,"locknet_main msgrcv errno = %d, errmsg = %s\n", errno,strerror(errno));
+ }
+ }
+
+ return 0;
+}
diff --git a/ap/app/zte_comm/zte_locknet/src/zctrm_locknet_proc.c b/ap/app/zte_comm/zte_locknet/src/zctrm_locknet_proc.c
new file mode 100755
index 0000000..01e220a
--- /dev/null
+++ b/ap/app/zte_comm/zte_locknet/src/zctrm_locknet_proc.c
@@ -0,0 +1,2191 @@
+#include "zctrm_locknet.h"
+//#include "drvs_efuse.h"
+#include "zctrm_ln_rsa.h"
+#include "zctrm_ln_md5.h"
+#include "RONvParam_AMT.h"
+//#include "ps_normal.h"
+//#include "ps_wifi.h"
+#include <limits.h>
+
+static BOOL g_IsDigestKeyGot = FALSE;
+static BOOL g_IsSetListKeyGot = FALSE;
+
+static BOOL g_IsSetListAuthSucc = FALSE;
+static BOOL g_NeedSecondList = FALSE;
+static BOOL g_IsKeyExist = FALSE;
+static BOOL g_IsDigestGotSucc = FALSE;
+
+static BOOL g_IsUnlockKeyGot = FALSE;
+static UINT8 g_UnlockKeyPlaint[LOCKNET_KEY_LEN+1] = {0};
+
+static UINT8 g_SetListPlaint[LOCKNET_KEY_LEN+1] = {0};
+
+static T_ZDrvEfuse_Secure g_Efuse_Secure={0};
+
+T_zCtrm_LockListPara simLockListPara = {0};
+T_zCtrm_SIMPara simPara = {0};
+SINT32 g_Sec_Status = ENCRYPT_INITING;
+extern int sendflag;
+
+SINT32 zCtrm_Atohex(CHAR c)
+{
+ SINT32 result = 0;
+
+ if(c >= '0' && c <= '9')
+ {
+ result = c - '0';
+ }
+ else if(c>='a' && c<='f')
+ {
+ result = (c - 'a') + 10;
+ }
+ else if(c>='A' && c<='F')
+ {
+ result = (c - 'A') + 10;
+ }
+ else
+ {
+ at_print(AT_ERR,"zCtrm_Atohex error,can unknown char:%c\n",c);
+ return result;
+ }
+ return result;
+}
+
+static SINT32 zCtrm_Strnicmp(const CHAR * cs,const CHAR * ct,UINT32 count)
+{
+ SINT32 res = 0;
+
+ while (count)
+ {
+ if ((res = toupper(*cs)- toupper(*ct++)) != 0 || !*cs++)
+ break;
+ count--;
+ }
+
+ return res;
+}
+VOID ConvertToBigEndian(unsigned int *data)
+{
+ *data = ((*data & 0xff000000) >> 24)
+ | ((*data & 0x00ff0000) >> 8)
+ | ((*data & 0x0000ff00) << 8)
+ | ((*data & 0x000000ff) << 24) ;
+}
+
+static UINT32 zCtrm_Bytes2String(const UINT8* pSrc, CHAR* pDst, UINT16 srcLength)
+{
+ const UINT8 tab[]="0123456789ABCDEF";
+ int iSrc=0;
+
+#if 1 // cov M srcLength is unsigned
+ if(pSrc == NULL || pDst == NULL )
+ {
+ return -1;
+ }
+
+#else
+ if(pSrc == NULL || pDst == NULL || srcLength < 0)
+ {
+ return -1;
+ }
+#endif
+ for(iSrc=0; iSrc<srcLength; iSrc++)
+ {
+ *pDst++ = tab[*pSrc >> 4];
+ *pDst++ = tab[*pSrc & 0x0f];
+ pSrc++;
+ }
+
+ *pDst = '\0';
+
+ return srcLength * 2;
+}
+
+static UINT32 makeLocknetKeyRandom(VOID)
+{
+ UINT32 val = 0;
+ UINT32 seed = (UINT32)time( NULL );
+ int fd = open("/dev/urandom",O_RDONLY);
+
+ if(fd >= 0)
+ {
+ int i = 0;
+ UINT32 rand = 0;
+ for(i = 0; i < 128; i++)
+ {
+ if(read(fd, &rand, sizeof(rand)) > 0)
+ {
+ if(rand > UINT_MAX-1) // kw 3 cov M
+ {
+ rand = UINT_MAX;
+ }
+ seed += rand;
+ if(seed > UINT_MAX-1) // kw 3 cov M
+ {
+ seed = UINT_MAX;
+ }
+ }
+ }
+ close(fd);
+ }
+
+ srand(seed);
+ val = rand() + (rand() ^ 2) + 1;
+ val %= 100000000;
+
+ return val;
+}
+
+static VOID zCtrm_LocknetKeyGen(UINT8 *plainText, UINT16 len)
+{
+ UINT32 r1 = 0;
+ UINT32 r2 = 0;
+ UINT8 key[LOCKNET_KEY_LEN + 1] = {0};
+
+ r1 = makeLocknetKeyRandom();
+ r2 = makeLocknetKeyRandom();
+ snprintf((char *)key, sizeof(key),"%08ld%08ld", r1, r2);
+ memcpy(plainText, key, len);
+ at_print(AT_ERR,"zCtrm_LocknetKeyGen:plainText = %s\n",plainText);
+}
+
+static UINT32 zCtrm_RsaPublicEncrypt(const UINT8 *plainText, UINT8 *cipherText,const char *rsa_n,const char *rsa_e)
+{
+ rsa_context rsa;
+
+ rsa_init(&rsa, RSA_PKCS_V15, 0);
+
+ rsa.len = KEY_LEN;
+ mpi_read_string(&rsa.N, 16, rsa_n);
+ mpi_read_string(&rsa.E, 16, rsa_e);
+
+ if(rsa_check_pubkey(&rsa) != 0)
+ {
+ at_print(AT_ERR,"Encode check failed\n");
+ return EXT_ERROR;
+ }
+ if(rsa_public(&rsa, plainText, cipherText) != 0)
+ {
+ at_print(AT_ERR,"Encode check failed\n");
+ return EXT_ERROR;
+ }
+ rsa_free(&rsa);
+
+ at_print(AT_ERR,"Encode passed\n");
+ return EXT_SUCCESS;
+}
+
+//½«´ÓefuseÖжÁÈ¡µÄ¹«Ô¿²ÎÊý£¬½øÐдóС¶Ë´æ´¢×ª»»(±¾ÉíΪС¶Ë´æ´¢)
+UINT32 zCtrm_RsaPublicEncryptProc(const UINT8 *plainText, UINT8 *cipherText)
+{
+ UINT32 retCode = EXT_ERROR;
+ unsigned int i;
+ UINT32 pubKeyRsaEOrder[32]={0};
+ UINT32 pubKeyRsaNOrder[32]={0};
+ char pubKeyRsaEtext[KEY_LEN*2+1]={0};
+ char pubKeyRsaNtext[KEY_LEN*2+1]={0};
+ int efuse_fd = -1;
+ int ret = -1;
+
+ memset(&g_Efuse_Secure,0,sizeof(g_Efuse_Secure));
+
+ efuse_fd = open("/dev/efuse", O_RDWR);
+ if (efuse_fd < 0) {
+ at_print(AT_ERR,"zCtrm_RsaPublicEncryptProc: efuse fd_func open fail.\n");
+ return EXT_ERROR;//klocwork
+ }
+
+ ret = ioctl(efuse_fd , EFUSE_GET_DATA, &g_Efuse_Secure);
+
+ at_print(AT_ERR,"[zCtrm_RsaPublicEncryptProc]: pubKeyRsaE[%x] pubKeyRsaN[%x]\n",ret,g_Efuse_Secure.pubKeyRsaE[31],g_Efuse_Secure.pubKeyRsaN[0]);
+ close(efuse_fd);//klocwork
+ /*if(g_Efuse_Secure.pubKeyRsaN ==NULL || g_Efuse_Secure.pubKeyRsaE ==NULL)
+ {
+ at_print(AT_ERR,"Rsa NULL\n");
+ return EXT_ERROR;
+ }*/
+
+ memcpy(pubKeyRsaEOrder,g_Efuse_Secure.pubKeyRsaE,sizeof(g_Efuse_Secure.pubKeyRsaE));
+ for(i=0;i<32;i++)
+ {
+ ConvertToBigEndian(&pubKeyRsaEOrder[i]);
+ }
+ zCtrm_Bytes2String(pubKeyRsaEOrder, pubKeyRsaEtext, KEY_LEN);
+
+ memcpy(pubKeyRsaNOrder,g_Efuse_Secure.pubKeyRsaN,sizeof(g_Efuse_Secure.pubKeyRsaN));
+ for(i=0;i<32;i++)
+ {
+ ConvertToBigEndian(&pubKeyRsaNOrder[i]);
+ }
+ zCtrm_Bytes2String(pubKeyRsaNOrder, pubKeyRsaNtext, KEY_LEN);
+
+ at_print(AT_ERR,"zCtrm_RsaPublicEncryptProc:RsaN = %s\n",pubKeyRsaNtext);
+ at_print(AT_ERR,"zCtrm_RsaPublicEncryptProc:RsaE = %s\n",pubKeyRsaEtext);
+
+ return zCtrm_RsaPublicEncrypt(plainText,cipherText,pubKeyRsaNtext,pubKeyRsaEtext);
+}
+
+static BOOL zCtrm_IsParaNum(UINT8 *data, UINT16 dataLen)
+{
+ UINT16 idata = 0;
+
+ if(*data == '\0')
+ {
+ return TRUE;
+ }
+
+ for(idata = 0; idata < dataLen; idata++)
+ {
+ if(*data < '0' || *data > '9')
+ {
+ at_print(AT_ERR,"zCtrm_IsParaNum error:%c!\n",*data);
+ return FALSE;
+ }
+ data++;
+ }
+ return TRUE;
+}
+
+static UINT32 zCtrm_CheckListPara(UINT8 *data, UINT16 dataLen)
+{
+ UINT8 *pBegin = data;
+ UINT8 *pEnd = NULL;
+ UINT16 subLen = 0;
+ UINT16 iPara = 0;
+
+ for(iPara = 0; iPara < LOCKNET_ITEM_NUM; iPara++)
+ {
+ if(iPara < LOCKNET_ITEM_NUM - 1)
+ {
+ pEnd = strchr(pBegin,',');
+ if (pEnd == NULL)//klocwork
+ return EXT_ERROR;
+ subLen = pEnd - pBegin;
+ }
+ else
+ {
+ subLen = dataLen - (pBegin - data);
+ }
+
+ switch(iPara)
+ {
+ case PARA_MCC:
+ case PARA_MNC:
+ {
+ if(subLen > 3 || FALSE == zCtrm_IsParaNum(pBegin,subLen))
+ {
+ return EXT_ERROR;
+ }
+ break;
+ }
+ case PARA_IMSI6:
+ case PARA_IMSI7:
+ {
+ if(subLen > 1 || FALSE == zCtrm_IsParaNum(pBegin,subLen))
+ {
+ return EXT_ERROR;
+ }
+ break;
+ }
+ case PARA_GID1:
+ case PARA_GID2:
+ {
+ if(subLen > USED_GID_LEN) //one at, need opt
+ {
+ return EXT_ERROR;
+ }
+ break;
+ }
+ default:
+ {
+ return EXT_ERROR;
+ }
+ }
+
+ pBegin = pEnd + 1;
+ }
+
+ return EXT_SUCCESS;
+}
+
+static UINT32 zCtrm_CheckListNum(UINT8 *data, UINT16 dataLen, UINT16 *listnum)
+{
+ UINT8 *pBegin = NULL;
+ UINT8 *pEnd = NULL;
+ UINT16 iData = 0;
+ UINT16 count = 0;
+ UINT16 maxNum = LOCKNET_FIRST_NUM;
+
+ pBegin=data;
+ for(iData = 0; iData < dataLen; iData++)
+ {
+ if(*pBegin == ';')
+ {
+ count++;
+ }
+ pBegin++;
+ }
+
+ if(g_NeedSecondList == TRUE)
+ {
+ maxNum = LOCKNET_MAX_NUM - LOCKNET_FIRST_NUM;
+ }
+
+ if(count < 1 || count > maxNum)
+ {
+ return EXT_ERROR;
+ }
+
+ pEnd=strrchr(data,';');
+ if (pEnd == NULL)//klocwork
+ return EXT_ERROR;
+ if(('\0' == *(char *)(pEnd+1))||(0 == strncmp(pEnd+1,"next",strlen("next")) && count == LOCKNET_FIRST_NUM) )
+ {
+ *listnum = count;
+ at_print(AT_ERR,"zCtrm_CheckListNum pEnd:--%s--\n",pEnd);
+ return EXT_SUCCESS;
+ }
+
+ at_print(AT_ERR,"zCtrm_CheckListNum err:--%s--\n",pEnd);
+ return EXT_ERROR;
+
+}
+
+static VOID zCtrm_GetListPara(UINT8 *data, UINT16 dataLen, T_zCtrm_LockListPara *para)
+{
+ UINT8 *pBegin = data;
+ UINT8 *pEnd = NULL;
+ UINT16 subLen = 0;
+ UINT16 iPara = 0;
+
+ for(iPara = 0; iPara < LOCKNET_ITEM_NUM; iPara++)
+ {
+ if(iPara < LOCKNET_ITEM_NUM -1)
+ {
+ pEnd = strchr(pBegin,',');
+ if (pEnd == NULL)//klocwork
+ return;
+ subLen = pEnd - pBegin;
+ }
+ else
+ {
+ subLen = dataLen - (pBegin - data);
+ }
+
+ switch(iPara)
+ {
+ case PARA_MCC:
+ {
+ if (subLen < sizeof(para->mcc)) {//klocwork
+ memset(para->mcc,0,sizeof(para->mcc));
+ snprintf(para->mcc,subLen+1,"%s",pBegin);
+ //strncpy(para->mcc,pBegin,subLen);
+ }
+ break;
+ }
+ case PARA_MNC:
+ {
+ if (subLen < sizeof(para->mnc)) {
+ memset(para->mnc,0,sizeof(para->mnc));
+ snprintf(para->mnc,subLen+1,"%s",pBegin);
+ //strncpy(para->mnc,pBegin,subLen);
+ }
+ break;
+ }
+ case PARA_IMSI6:
+ {
+ if (subLen < sizeof(para->imsi6)) {
+ memset(para->imsi6,0,sizeof(para->imsi6));
+ snprintf(para->imsi6,subLen+1,"%s",pBegin);
+ //strncpy(para->imsi6,pBegin,subLen);
+ }
+ break;
+ }
+ case PARA_IMSI7:
+ {
+ if (subLen < sizeof(para->imsi7)) {
+ memset(para->imsi7,0,sizeof(para->imsi7));
+ snprintf(para->imsi7,subLen+1,"%s",pBegin);
+ //strncpy(para->imsi7,pBegin,subLen);
+ }
+ break;
+ }
+ case PARA_GID1:
+ {
+ if (subLen < sizeof(para->gid1)) {
+ memset(para->gid1,0,sizeof(para->gid1));
+ snprintf(para->gid1,subLen+1,"%s",pBegin);
+ //strncpy(para->gid1,pBegin,subLen);
+ }
+ break;
+ }
+ case PARA_GID2:
+ {
+ if (subLen < sizeof(para->gid2)) {
+ memset(para->gid2,0,sizeof(para->gid2));
+ snprintf(para->gid2,subLen+1,"%s",pBegin);
+ //strncpy(para->gid2,pBegin,subLen);
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ pBegin = pEnd + 1;
+ }
+
+}
+
+static UINT32 zCtrm_CleanAmtList(VOID)
+{
+ UINT32 retCode = EXT_ERROR;
+ UINT16 iList = 0;
+ T_zCtrm_LockListPara lockList = {0};
+
+ memset((UINT8 *)&lockList,0xFF,sizeof(lockList));
+ for(iList = 0; iList < LOCKNET_MAX_NUM; iList++)
+ {
+
+
+ cpnv_ChangeNvRoAttr(1);
+ //retCode = zDrvNand_Program(AMT_LOCKNET_LIST + iList*sizeof(lockList), sizeof(lockList), (UINT8 *)&lockList);
+ retCode = cpnv_NvItemWriteNvro(AMT_LOCKNET_LIST + iList*sizeof(lockList), (UINT8 *)&lockList, sizeof(lockList));
+ cpnv_FsGcWait(FS_NVROFS);
+ cpnv_ChangeNvRoAttr(0);
+ if (EXT_SUCCESS != retCode )
+ {
+ return EXT_ERROR;
+ }
+
+ }
+ return EXT_SUCCESS;
+}
+
+static UINT32 zCtrm_WriteLocklist(UINT8 *data, UINT16 dataLen)
+{
+ UINT8 *pBegin = data;
+ UINT8 *pEnd = NULL;
+ UINT8 tStr[LOCKNET_MAX_AT_LEN] = {0};
+ UINT16 listCount = 0;
+ UINT16 iList = 0;
+ UINT16 offset = 0;
+ UINT32 retCode = EXT_ERROR;
+
+ if(EXT_SUCCESS != zCtrm_CheckListNum(data, dataLen, &listCount))
+ {
+ return EXT_ERROR;
+ }
+ at_print(AT_ERR,"zCtrm_WriteLocklist listcount:%d!\n",listCount);
+
+ if(g_NeedSecondList == TRUE)
+ {
+ offset = LOCKNET_FIRST_NUM;
+ }
+ else
+ {
+ if(zCtrm_CleanAmtList() != EXT_SUCCESS)
+ {
+ return EXT_ERROR;
+ }
+ }
+
+ for(iList = 0; iList < listCount; iList++)
+ {
+ T_zCtrm_LockListPara lockList = {0};
+ unsigned int slen = 0;//klocwork
+
+ pEnd=strchr(pBegin,';');
+ if (pEnd == NULL)//klocwork
+ return EXT_ERROR;
+ slen = pEnd-pBegin;
+ if(slen < sizeof(tStr)) {
+ memset(tStr,0,sizeof(tStr));
+ snprintf(tStr,slen+1,"%s",pBegin);
+ //strncpy(tStr,pBegin,slen);
+ } else {
+ return EXT_ERROR;
+ }
+
+ zCtrm_GetListPara(tStr,slen,&lockList);
+
+ cpnv_ChangeNvRoAttr(1);
+ //retCode = zDrvNand_Program(AMT_LOCKNET_LIST + (offset + iList)*sizeof(lockList), sizeof(lockList), (UINT8 *)&lockList);
+ retCode = cpnv_NvItemWriteNvro(AMT_LOCKNET_LIST + (offset + iList)*sizeof(lockList), (UINT8 *)&lockList, sizeof(lockList));
+ cpnv_FsGcWait(FS_NVROFS);
+ cpnv_ChangeNvRoAttr(0);
+ if (EXT_SUCCESS != retCode )
+ {
+ return EXT_ERROR;
+ }
+
+ pBegin = pEnd + 1;
+ }
+
+ return EXT_SUCCESS;
+}
+
+static UINT32 zCtrm_GetUnlockMaxTime(VOID)
+{
+ UINT32 retCode = EXT_ERROR;
+ UINT32 timet = 0;
+ char time[AT_STR_LEN] = {0};
+ //timet = atoi(cfg_get("zunlocktimes"));
+ sc_cfg_get("zunlocktimes", time, sizeof(time));
+ timet = atoi(time);
+ at_print(AT_ERR,"zCtrm_GetUnlockMaxTime:%d---\n" ,timet);
+
+ return timet;
+}
+
+static UINT32 zCtrm_LocknetNandSet(UINT8 *plainText, UINT16 len)
+{
+ T_zCtrm_LockLevel lockState = LOCKED;
+ UINT32 times = zCtrm_GetUnlockMaxTime();
+ UINT32 retCode = EXT_ERROR;
+
+ cpnv_ChangeNvRoAttr(1);
+
+ //retCode = zDrvNand_Program(AMT_LOCKNET_TIMES, sizeof(times),(UINT8 *)×);
+ retCode = cpnv_NvItemWriteNvro(AMT_LOCKNET_TIMES, (UINT8 *)×, sizeof(times));
+ if (EXT_SUCCESS != retCode)
+ {
+ cpnv_ChangeNvRoAttr(0);
+ return EXT_ERROR;
+ }
+
+ //retCode = zDrvNand_Program(AMT_LOCKNET_KEY, len, plainText);
+ retCode = cpnv_NvItemWriteNvro(AMT_LOCKNET_KEY, plainText, len);
+ if (EXT_SUCCESS != retCode)
+ {
+ cpnv_ChangeNvRoAttr(0);
+ return EXT_ERROR;
+ }
+
+ //retCode = zDrvNand_Program(AMT_LOCKNET_BASE, sizeof(lockState),(UINT8 *)&lockState);
+ retCode = cpnv_NvItemWriteNvro(AMT_LOCKNET_BASE, (UINT8 *)&lockState, sizeof(lockState));
+ if (EXT_SUCCESS != retCode)
+ {
+ cpnv_ChangeNvRoAttr(0);
+ return EXT_ERROR;
+ }
+ cpnv_FsGcWait(FS_NVROFS);
+ cpnv_ChangeNvRoAttr(0);
+ return EXT_SUCCESS;
+}
+
+static UINT32 zCtrm_LocknetStaticCheck(VOID)
+{
+ T_zCtrm_LockLevel lockState = LOCKFLAG_ERROR;
+ UINT32 retCode = EXT_ERROR;
+
+ //retCode = zDrvNand_Read(AMT_LOCKNET_BASE,sizeof(lockState),(UINT8 *)&lockState); //len=4
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_BASE, (UINT8 *)&lockState, sizeof(lockState));
+ at_print(AT_ERR,"zCtrm_LocknetStaticCheck ret=%d lockstat=%d\n",retCode,lockState);
+ if (EXT_SUCCESS == retCode)
+ {
+ if(lockState == NEVER_LOCKED)
+ {
+ return EXT_SUCCESS;
+ }
+ }
+
+ return EXT_ERROR;
+}
+
+static UINT32 zCtrm_LocknetListCheck(VOID)
+{
+ T_zCtrm_LockListPara lockList = {0};
+ UINT32 retCode = EXT_ERROR;
+
+ //retCode = zDrvNand_Read(AMT_LOCKNET_LIST, sizeof(lockList), (UINT8 *)&lockList);
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_LIST, (UINT8 *)&lockList, sizeof(lockList));
+ if (EXT_SUCCESS != retCode )
+ {
+ return EXT_ERROR;
+ }
+
+ if((lockList.mcc[0] == 0xFF)||(lockList.imsi6[0] == 0xFF)||(lockList.gid1[0] == 0xFF))
+ {
+ at_print(AT_ERR,"zCtrm_LocknetListCheck FF\n");
+ return EXT_ERROR;
+ }
+
+ return EXT_SUCCESS;
+}
+
+static UINT32 zCtrm_CheckLocklist(UINT8 *data, UINT16 dataLen)
+{
+ UINT8 *pBegin = data;
+ UINT8 *pEnd = NULL;
+ UINT16 iItem = 0;
+ UINT8 *pPara = NULL;
+ UINT16 listCount = 0;
+ UINT16 paraCount = 0;
+
+ if(EXT_SUCCESS != zCtrm_CheckListNum(data, dataLen, &listCount))
+ {
+ return EXT_ERROR;
+ }
+ at_print(AT_ERR,"zCtrm_CheckLocklist listCount = %d\n",listCount);
+
+ for(iItem = 0; iItem < listCount; iItem++)
+ {
+ pEnd = strchr(pBegin,';');
+ if (pEnd == NULL)//klocwork
+ return EXT_ERROR;
+ paraCount = 0;
+ for(pPara = pBegin; pPara < pEnd; pPara++)
+ {
+ if(!((*pPara == ',')||(*pPara>='0'&&*pPara<='9')||(*pPara>='a'&&*pPara<='f')||(*pPara>='A'&&*pPara<='F')))
+ {
+ at_print(AT_ERR,"zCtrm_CheckLocklist error:%c!\n",*pPara);
+ return EXT_ERROR;
+ }
+
+ if(*pPara == ',')
+ {
+ paraCount++;
+ }
+ }
+
+ if(paraCount == LOCKNET_ITEM_NUM - 1)
+ {
+ if(EXT_SUCCESS != zCtrm_CheckListPara(pBegin, pEnd - pBegin))
+ {
+ return EXT_ERROR;
+ }
+ pBegin = pEnd + 1;
+ }
+ else
+ {
+ at_print(AT_ERR,"zCtrm_CheckLocklist count:%d!\n",paraCount);
+ return EXT_ERROR;
+ }
+
+ }
+ at_print(AT_ERR,"zCtrm_CheckLocklist succ!\n");
+ return EXT_SUCCESS;
+}
+
+static UINT32 zCtrm_LocknetDigestMD5Hash(char *psDest)
+{
+ md5_ctx stStc;
+ UINT32 retCode = EXT_ERROR;
+ char TmpImei[ZPS_ImeiLen]={0};//imei³¤¶È×î´óÖµ
+ UINT16 iList = 0;
+ char lockList[LIST_LEN] = {0};
+ UINT8 plainText[KEY_LEN] = {0};
+ UINT8 sTempBuf[16];
+ unsigned int i;
+
+ char PTmpImei[ZPS_ImeiLen*2+1]={0};
+ char PlockList[LIST_LEN*2+1]={0};
+ char PplainText[KEY_LEN*2+1]={0};
+
+ md5_init(&stStc);
+
+ //retCode = zPS_NvAMTItemRead(ABIMEI_NVPARAM, (unsigned char *)TmpImei, ZPS_ImeiLen);
+ retCode = cpnv_NvItemRead(OS_FLASH_AMT_COMM_RO_IMEI_ADDRESS, (unsigned char *)TmpImei, OS_FLASH_AMT_COMM_RO_IMEI_SIZE);
+
+ if (CPNV_ERROR == retCode)
+ {
+ return EXT_ERROR;
+ }
+ zCtrm_Bytes2String(TmpImei, PTmpImei, ZPS_ImeiLen);
+ at_print(AT_ERR,"zCtrm_LocknetDigestMD5Hash TmpImei=%s!\n",PTmpImei);
+ md5_update(&stStc, (unsigned char *)TmpImei, ZPS_ImeiLen);
+
+
+ //ËøÍø²ÎÊý
+ for(iList = 0; iList < LOCKNET_MAX_NUM; iList++)
+ {
+ //retCode = zDrvNand_Read(AMT_LOCKNET_LIST + iList*sizeof(lockList), sizeof(lockList), (UINT8 *)lockList);
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_LIST + iList*sizeof(lockList), (UINT8 *)lockList, sizeof(lockList));
+ if (EXT_SUCCESS != retCode )
+ {
+ return EXT_ERROR;
+ }
+ zCtrm_Bytes2String(lockList, PlockList, LIST_LEN);
+ at_print(AT_ERR,"zCtrm_LocknetDigestMD5Hash lockList=%s!\n",PlockList);
+ md5_update(&stStc, (unsigned char *)lockList, LIST_LEN);
+ }
+
+ //½âËøÂëÃÜÎÄ
+ //retCode = zDrvNand_Read(AMT_LOCKNET_KEY, sizeof(plainText), plainText);
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_KEY, plainText, sizeof(plainText));
+ if (EXT_SUCCESS != retCode)
+ {
+ return EXT_ERROR;
+ }
+ zCtrm_Bytes2String(plainText, PplainText, KEY_LEN);
+ at_print(AT_ERR,"zCtrm_LocknetDigestMD5Hash plainText=%s!\n",PplainText);
+ md5_update(&stStc, (unsigned char *)plainText, KEY_LEN);
+
+ md5_final(sTempBuf, &stStc);
+ for(i = 0; i < 16; i++)
+ {
+ snprintf(psDest + 2*i, 3, "%02x", sTempBuf[i]);
+ }
+ return EXT_SUCCESS;
+}
+
+static UINT32 zCtrm_String2Bytes(const CHAR* pSrc, UINT8* pDst, UINT16 srcLength)
+{
+ int i=0;
+
+ //УÑé²ÎÊý
+#if 1 // cov M srcLength is unsigned
+ if(pSrc == NULL || pDst == NULL)
+ {
+ return -1;
+ }
+#else
+ if(pSrc == NULL || pDst == NULL || srcLength < 0)
+ {
+ return -1;
+ }
+
+#endif
+
+ for(i = 0; i < srcLength; i += 2)
+ {
+ // Êä³ö¸ß4λ
+ if(*pSrc >= '0' && *pSrc <= '9')
+ {
+ *pDst = (*pSrc - '0') << 4;
+ }
+ else
+ {
+ *pDst = ((toupper(*pSrc) - 'A') + 10) << 4;
+ }
+
+ pSrc++;
+
+ // Êä³öµÍ4λ
+ if(*pSrc >= '0' && *pSrc <= '9')
+ {
+ *pDst |= *pSrc - '0';
+ }
+ else
+ {
+ *pDst |= (toupper(*pSrc) - 'A') + 10;
+ }
+
+ pSrc++;
+ pDst++;
+ }
+
+ // ·µ»ØÄ¿±êÊý¾Ý³¤¶È
+ return srcLength / 2;
+}
+
+int zCtrm_LocknetAuthList(char *at_paras)
+{
+ UINT8 *pBegin = NULL;
+ UINT8 *pEnd = NULL;
+ UINT16 keyLen = 0;
+ UINT8 keyBuf[LOCKNET_KEY_LEN+1] = {0};
+ UINT8 *pStrAt = NULL;
+ CHAR at_str[AT_STR_LEN] = {0};
+
+ pStrAt = strstr(at_paras,"a,");
+ if(pStrAt != NULL)
+ {
+ if (g_IsSetListKeyGot != TRUE)
+ {
+ at_print(AT_ERR,"zCtrm_LocknetAuthList:KeyGot false\n");
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR\r\n");
+ goto end;
+ }
+ pEnd = at_paras+strlen(at_paras);
+
+ pBegin = pStrAt + strlen("a,");
+ keyLen = pEnd - pBegin;
+ if (keyLen != LOCKNET_KEY_LEN)
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR\r\n");
+ goto end;
+ }
+ memcpy(keyBuf,pBegin,keyLen);
+ if(memcmp(keyBuf,g_SetListPlaint,keyLen) != 0)
+ {
+ at_print(AT_ERR,"zCtrm_LocknetAuthList:Key error\n");
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR\r\n");
+ goto end;
+ }
+ snprintf(at_str,AT_STR_LEN,"\r\nOK\r\n");
+ g_IsSetListKeyGot = FALSE;
+ g_IsSetListAuthSucc = TRUE;
+ goto end;
+ }
+ else
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR\r\n");
+ goto end;
+ }
+end:
+ send_rsp_str_to_farps(MODULE_ID_LOCKNET, at_str, strlen(at_str));
+ return 0;
+}
+
+int zCtrm_LocknetAuthGen()
+{
+ UINT32 retCode = EXT_ERROR;
+ UINT8 plainText[LOCKNET_KEY_LEN+1] = {0};
+ UINT8 plainText128[KEY_LEN] = {0};
+ UINT8 cipherText[KEY_LEN] = {0};
+ CHAR cipherHex[KEY_LEN*2+1] = {0};
+ CHAR at_str[AT_STR_LEN+KEY_LEN*2] = {0};
+
+ if (g_IsSetListKeyGot != FALSE)
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:Already authorized\r\n");
+ goto end;
+ }
+ zCtrm_LocknetKeyGen(plainText, LOCKNET_KEY_LEN);
+ memcpy(plainText128+KEY_LEN-LOCKNET_KEY_LEN, plainText, LOCKNET_KEY_LEN);
+ retCode = zCtrm_RsaPublicEncryptProc(plainText128, cipherText);
+ if (EXT_SUCCESS != retCode )
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR\r\n");
+ goto end;
+ }
+ zCtrm_Bytes2String(cipherText, cipherHex, KEY_LEN);
+
+ memset(g_SetListPlaint,0,sizeof(g_SetListPlaint));
+ memcpy(g_SetListPlaint,plainText,sizeof(g_SetListPlaint)-1);
+ snprintf(at_str,AT_STR_LEN+KEY_LEN*2,"\r\n+LOCKLISTAUTH: %s\r\nOK\r\n",cipherHex);
+ g_IsSetListKeyGot = TRUE;
+ goto end;
+end:
+ send_rsp_str_to_farps(MODULE_ID_LOCKNET, at_str, strlen(at_str));
+ return 0;
+}
+
+int zCtrm_LocknetAuthProc(MSG_BUF *msg)
+{
+ char at_str[AT_STR_LEN] = {0};
+
+ at_print(AT_ERR,"zCtrm_LocknetAuthProc\n");
+ if('g' == (char*)msg->aucDataBuf[0])
+ {
+ zCtrm_LocknetAuthGen();
+ }
+ else if('a' == (char*)msg->aucDataBuf[0])
+ {
+ zCtrm_LocknetAuthList((char*)msg->aucDataBuf);
+ }
+ else
+ {
+ at_print(AT_ERR,"zCtrm_LocknetAuthProc:param error!!!\n");
+ goto error;
+ }
+ return 0;
+error:
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR\r\n");
+ send_rsp_str_to_farps(MODULE_ID_LOCKNET, at_str, strlen(at_str));
+ return 0;
+
+}
+
+int zCtrm_LocknetListSet(MSG_BUF *msg)
+{
+ UINT32 retCode = EXT_ERROR;
+ UINT16 dataLen = 0;
+ CHAR at_str[AT_STR_LEN] = {0};
+ char *at_paras = NULL; // cov M PW.BRANCH_PAST_INITIALIZATION
+
+ if (g_IsSetListAuthSucc != TRUE)
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:unauthorized\r\n");
+ goto end;
+ }
+ at_paras = (char*)msg->aucDataBuf;
+ dataLen = strlen(at_paras);
+ at_print(AT_ERR,"dataLen = %d\n",dataLen);
+ retCode = zCtrm_CheckLocklist((char*)msg->aucDataBuf, dataLen);
+ if (EXT_SUCCESS != retCode )
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:invalid parameter\r\n");
+ goto end;
+ }
+ retCode = zCtrm_WriteLocklist(at_paras, dataLen);
+ if (EXT_SUCCESS != retCode )
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:flash failed\r\n");
+ goto end;
+ }
+ if(NULL != strstr(at_paras,"next"))
+ {
+ g_NeedSecondList = TRUE;
+ }
+ else
+ {
+ g_NeedSecondList = FALSE;
+ }
+ snprintf(at_str,AT_STR_LEN,"\r\nOK\r\n");
+ goto end;
+end:
+ send_rsp_str_to_farps(MODULE_ID_LOCKNET, at_str, strlen(at_str));
+ return 0;
+}
+
+int zCtrm_LocknetKeyGenerate()
+{
+ UINT32 retCode = EXT_ERROR;
+ UINT8 plainText[LOCKNET_KEY_LEN+1] = {0};
+ UINT8 plainText128[KEY_LEN] = {0};
+ UINT8 cipherText[KEY_LEN] = {0};
+ CHAR at_str[AT_STR_LEN] = {0};
+ //need open
+ retCode = zCtrm_LocknetStaticCheck();
+ if (EXT_SUCCESS != retCode )
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:locknet already exists\r\n");
+ goto end;
+ }
+
+ retCode = zCtrm_LocknetListCheck();
+ if (EXT_SUCCESS != retCode )
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:missing locknet file\r\n");
+ goto end;
+ }
+ zCtrm_LocknetKeyGen(plainText, LOCKNET_KEY_LEN);
+ at_print(AT_ERR,"zCtrm_ExtLocknetKeyGenerate plainText=%s!\n",plainText);
+ memcpy(plainText128+KEY_LEN-LOCKNET_KEY_LEN, plainText, LOCKNET_KEY_LEN);
+ retCode = zCtrm_RsaPublicEncryptProc(plainText128, cipherText);
+ if (EXT_SUCCESS != retCode )
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:Encrypt error\r\n");
+ goto end;
+ }
+ retCode = zCtrm_LocknetNandSet(cipherText, sizeof(cipherText));
+ if (EXT_SUCCESS != retCode )
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:invalid command\r\n");
+ goto end;
+ }
+ snprintf(at_str,AT_STR_LEN,"\r\nOK\r\n");
+ g_IsKeyExist = TRUE;
+ goto end;
+end:
+ send_rsp_str_to_farps(MODULE_ID_LOCKNET, at_str, strlen(at_str));
+ return 0;
+}
+
+int zCtrm_LocknetDelRand()
+{
+ UINT32 retCode = EXT_ERROR;
+ UINT8 pPtr[KEY_LEN*2+64] = {0};
+ UINT8 plainText[LOCKNET_KEY_LEN+1] = {0};
+ UINT8 plainText128[KEY_LEN] = {0};
+ UINT8 cipherText[KEY_LEN] = {0};
+ CHAR cipherHex[KEY_LEN*2+1] = {0};
+ CHAR at_str[AT_STR_LEN+KEY_LEN*2] = {0};
+
+ if (g_IsUnlockKeyGot != FALSE)
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:Already authorized\r\n");
+ goto end;
+ }
+
+ zCtrm_LocknetKeyGen(plainText, LOCKNET_KEY_LEN);
+ memcpy(plainText128+KEY_LEN-LOCKNET_KEY_LEN, plainText, LOCKNET_KEY_LEN);
+ retCode = zCtrm_RsaPublicEncryptProc(plainText128, cipherText);
+ if (EXT_SUCCESS != retCode )
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR\r\n");
+ goto end;
+ }
+
+ zCtrm_Bytes2String(cipherText, cipherHex, KEY_LEN);
+
+ memset(g_UnlockKeyPlaint,0,sizeof(g_UnlockKeyPlaint));
+ memcpy(g_UnlockKeyPlaint,plainText,sizeof(g_UnlockKeyPlaint)-1);
+
+ snprintf(at_str,AT_STR_LEN+KEY_LEN*2,"\r\n+UNLOCKKEY:%s\r\nOK\r\n",cipherHex);
+ g_IsUnlockKeyGot = TRUE;
+ goto end;
+end:
+ send_rsp_str_to_farps(MODULE_ID_LOCKNET, at_str, strlen(at_str));
+ return 0;
+
+}
+
+static UINT32 zCtrm_LocknetNandDel(VOID)
+{
+ T_zCtrm_LockLevel lockState = NEVER_LOCKED;
+ UINT8 keyBuf[KEY_LEN] = {0};
+ UINT32 retCode = EXT_ERROR;
+
+ cpnv_ChangeNvRoAttr(1);
+ memset(keyBuf,0xFF,sizeof(keyBuf));
+ //retCode = zDrvNand_Program(AMT_LOCKNET_KEY, sizeof(keyBuf), keyBuf);
+ retCode = cpnv_NvItemWriteNvro(AMT_LOCKNET_KEY, keyBuf, sizeof(keyBuf));
+ if (EXT_SUCCESS != retCode)
+ {
+ cpnv_ChangeNvRoAttr(0);
+ return EXT_ERROR;
+ }
+
+ //retCode = zDrvNand_Program(AMT_LOCKNET_BASE, sizeof(lockState),(UINT8 *)&lockState);
+ retCode = cpnv_NvItemWriteNvro(AMT_LOCKNET_BASE, (UINT8 *)&lockState, sizeof(lockState));
+ if (EXT_SUCCESS != retCode)
+ {
+ cpnv_ChangeNvRoAttr(0);
+ return EXT_ERROR;
+ }
+ cpnv_FsGcWait(FS_NVROFS);
+ cpnv_ChangeNvRoAttr(0);
+ return EXT_SUCCESS;
+}
+
+int zCtrm_LocknetKeyDelete(char *at_paras)
+{
+ UINT32 retCode = EXT_ERROR;
+ UINT8 *pBegin = NULL;
+ UINT8 *pEnd = NULL;
+ UINT16 keyLen = 0;
+ UINT8 keyBuf[LOCKNET_KEY_LEN+1] = {0};
+ UINT8 *pStrAt = NULL;
+ CHAR at_str[AT_STR_LEN] = {0};
+
+ if (g_IsUnlockKeyGot != TRUE)
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR\r\n");
+ goto end;
+ }
+ pEnd = at_paras+strlen(at_paras);
+ pBegin = at_paras + strlen("d,");
+ keyLen = pEnd - pBegin;
+ if (keyLen != LOCKNET_KEY_LEN)
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR\r\n");
+ goto end;
+ }
+ memcpy(keyBuf,pBegin,keyLen);
+ if(memcmp(keyBuf,g_UnlockKeyPlaint,keyLen) != 0)
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR\r\n");
+ goto end;
+ }
+ retCode = zCtrm_LocknetNandDel();
+ if (EXT_SUCCESS != retCode )
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR\r\n");
+ goto end;
+ }
+
+ snprintf(at_str,AT_STR_LEN,"\r\nOK\r\n");
+ g_IsUnlockKeyGot = FALSE;
+ goto end;
+end:
+ send_rsp_str_to_farps(MODULE_ID_LOCKNET, at_str, strlen(at_str));
+ return 0;
+}
+
+int zCtrm_LocknetKeyProc(MSG_BUF *msg)
+{
+ UINT32 retCode = EXT_ERROR;
+ //UINT8 plainText[LOCKNET_KEY_LEN+1] = {0};
+ UINT8 plainText128[KEY_LEN] = {0};
+ UINT8 cipherText[KEY_LEN] = {0};
+
+ char *at_paras = (char*)msg->aucDataBuf;
+ if('g' == at_paras[0])
+ {
+ zCtrm_LocknetKeyGenerate();
+ }
+ if('c' == at_paras[0])
+ {
+ zCtrm_LocknetDelRand();
+ }
+ if('d' == at_paras[0])
+ {
+ zCtrm_LocknetKeyDelete(at_paras);
+ }
+ return 0;
+}
+
+int zCtrm_LocknetAmtStatus(MSG_BUF *msg)
+{
+ UINT32 retCode = EXT_ERROR;
+ UINT8 cipherText[KEY_LEN] = {0};
+ CHAR cipherHex[KEY_LEN*2+1] = {0};
+ UINT8 keyBuf[KEY_LEN] = {0};
+ CHAR at_str[AT_STR_LEN+KEY_LEN*2] = {0};
+
+ //retCode = zDrvNand_Read(AMT_LOCKNET_KEY, sizeof(keyBuf), keyBuf);
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_KEY, keyBuf, sizeof(keyBuf));
+ if (EXT_SUCCESS != retCode || keyBuf[0] == 0xFF)
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:locknet not found\r\n");
+ goto end;
+ }
+ if(g_IsKeyExist != TRUE)
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:illegal command\r\n");
+ goto end;
+ }
+
+ if (g_IsDigestGotSucc != TRUE)
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:undigest\r\n");
+ goto end;
+ }
+ memcpy(cipherText, keyBuf, sizeof(keyBuf));
+ zCtrm_Bytes2String(cipherText, cipherHex, KEY_LEN);
+
+ snprintf(at_str,AT_STR_LEN+KEY_LEN*2,"\r\n+UNLOCKKEY:%s\r\nOK\r\n",cipherHex);
+ g_IsKeyExist = FALSE;
+ goto end;
+end:
+ send_rsp_str_to_farps(MODULE_ID_LOCKNET, at_str, strlen(at_str));
+ return 0;
+}
+
+/*
+*»ñȡժҪÐÅÏ¢
+*·µ»ØÉ豸ID¡¢ËøÍø²ÎÊýE¡¢½âËøÂëÃÜÎÄF¾MD5¼ÆËãºóµÄÕªÒªÐÅÏ¢
+*/
+int zCtrm_LocknetDigestGet(MSG_BUF *msg)
+{
+ char psDest[LOCKNET_KEY_LEN*2+1] = {0};
+ UINT8 pPtr[MAX_AMT_AT_LEN] = {0};
+ UINT32 retCode = EXT_ERROR;
+ CHAR at_str[AT_STR_LEN+LOCKNET_KEY_LEN*2] = {0};
+
+ if (g_IsDigestKeyGot != FALSE)
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:Already Digestget\r\n");
+ goto end;
+ }
+
+ if(g_IsKeyExist != TRUE)
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:illegal command\r\n");
+ goto end;
+ }
+ retCode=zCtrm_LocknetDigestMD5Hash(psDest);
+ if(retCode==EXT_ERROR)
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR\r\n");
+ goto end;
+ }
+ snprintf(at_str,AT_STR_LEN+LOCKNET_KEY_LEN*2,"\r\n+LOCKDIGEST: %s\r\nOK\r\n",psDest);
+ g_IsDigestKeyGot = TRUE;
+ goto end;
+end:
+ send_rsp_str_to_farps(MODULE_ID_LOCKNET, at_str, strlen(at_str));
+ return 0;
+
+}
+
+int zCtrm_LocknetSignSet(MSG_BUF *msg)
+{
+ UINT32 retCode = EXT_ERROR;
+ UINT8 *pBegin = NULL;
+ UINT8 *pEnd = NULL;
+ UINT16 keyLen = 0;
+ CHAR keyText[KEY_LEN*2+1]={0};
+ UINT8 keyHex[KEY_LEN] = {0};
+ CHAR at_str[AT_STR_LEN] = {0};
+
+ char *at_paras = NULL;// cov M PW.BRANCH_PAST_INITIALIZATION
+
+ if (g_IsDigestKeyGot != TRUE)
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:NO Digestget\r\n");
+ goto end;
+ }
+ at_paras = (char*)msg->aucDataBuf;
+ pEnd = at_paras+strlen(at_paras);
+
+ pBegin = at_paras;
+ keyLen = pEnd - pBegin;
+ if (keyLen != KEY_LEN*2)
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR\r\n");
+ goto end;
+ }
+ memcpy(keyText,pBegin,keyLen);
+ //°Ñ×Ö·û´®×ª³É¶þ½øÖÆÊý´æ½øÈ¥
+ zCtrm_String2Bytes(keyText, keyHex, keyLen);
+ cpnv_ChangeNvRoAttr(1);
+ //retCode = zDrvNand_Program(AMT_LOCKNET_SIGN, KEY_LEN, keyHex);
+ retCode = cpnv_NvItemWriteNvro(AMT_LOCKNET_SIGN, keyHex, KEY_LEN);
+ if (EXT_SUCCESS != retCode)
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR\r\n");
+ cpnv_ChangeNvRoAttr(0);
+ goto end;
+ }
+ cpnv_FsGcWait(FS_NVROFS);
+ cpnv_ChangeNvRoAttr(0);
+ snprintf(at_str,AT_STR_LEN,"\r\nOK\r\n");
+ g_IsDigestKeyGot = FALSE;
+ g_IsDigestGotSucc = TRUE;
+ goto end;
+end:
+ send_rsp_str_to_farps(MODULE_ID_LOCKNET, at_str, strlen(at_str));
+ return 0;
+
+}
+
+int zCtrm_LocknetLevel(MSG_BUF *msg)
+{
+ UINT32 retCode = EXT_ERROR;
+ CHAR at_str[AT_STR_LEN] = {0};
+ T_zCtrm_LockLevel lockState = LOCKFLAG_ERROR;
+ //retCode = zDrvNand_Read(AMT_LOCKNET_BASE,sizeof(lockState),(UINT8 *)&lockState); //len=4
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_BASE, (UINT8 *)&lockState, sizeof(lockState));
+ if (EXT_SUCCESS != retCode )
+ {
+ at_print(AT_ERR,"zCtrm_ExtLocknetLevel read err\n");
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR\r\n");
+ goto end;
+ }
+ if(lockState == ALREADY_UNLOCKED)
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+LOCKLEVEL:Already Unlocked\r\nOK\r\n");
+ }
+ else if(lockState == LOCKED)
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+LOCKLEVEL:Locked\r\nOK\r\n");
+ }
+ else if(lockState == NEVER_LOCKED)
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+LOCKLEVEL:Never Locked\r\nOK\r\n");
+ }
+ else
+ {
+ at_print(AT_ERR,"zCtrm_ExtLocknetLevel err flag:%x\n",lockState);
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR\r\n");
+ goto end;
+ }
+ goto end;
+end:
+ send_rsp_str_to_farps(MODULE_ID_LOCKNET, at_str, strlen(at_str));
+ return 0;
+}
+
+int zCtrm_LocknetListGet()
+{
+ UINT32 retCode = EXT_ERROR;
+ UINT16 iList = 0;
+ UINT8 pPtr[MAX_AMT_AT_LEN] = {0};
+ CHAR at_str[AT_STR_LEN+MAX_AMT_AT_LEN] = {0};
+
+ T_zCtrm_LockListPara lockList = {0};
+ for(iList = 0; iList < LOCKNET_MAX_NUM; iList++)
+ {
+ memset(&lockList, 0, sizeof(lockList));//cov
+ //retCode = zDrvNand_Read(AMT_LOCKNET_LIST + iList*sizeof(lockList), sizeof(lockList), (UINT8 *)&lockList);
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_LIST + iList*sizeof(lockList), (UINT8 *)&lockList, sizeof(lockList));
+ if (EXT_SUCCESS != retCode )
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR\r\n");
+ send_rsp_str_to_farps(MODULE_ID_LOCKNET, at_str, strlen(at_str));
+ return 0;
+ }
+ if((lockList.mcc[0] == 0xFF)||(lockList.imsi6[0] == 0xFF)||(lockList.gid1[0] == 0xFF))
+ {
+ at_print(AT_ERR,"zCtrm_ExtLocknetListGet break iList:[%d]\n",iList);
+ break;
+ }
+ //cov
+ lockList.mcc[LIST_MCCMNC_LEN-1] = '\0';
+ lockList.mnc[LIST_MCCMNC_LEN-1] = '\0';
+ lockList.imsi6[LIST_IMSI_LEN-1] = '\0';
+ lockList.imsi7[LIST_IMSI_LEN-1] = '\0';
+ lockList.gid1[LIST_GID_LEN-1] = '\0';
+ lockList.gid2[LIST_GID_LEN-1] = '\0';
+ if(iList < LOCKNET_FIRST_NUM)
+ {
+ snprintf(pPtr+strlen(pPtr),sizeof(pPtr)-strlen(pPtr),"%s,%s,%s,%s,%s,%s;",
+ lockList.mcc,lockList.mnc,lockList.imsi6,lockList.imsi7,lockList.gid1,lockList.gid2);
+ }
+ else
+ {
+ strcat((char *)pPtr,"next");
+ break;
+ }
+
+ }
+ snprintf(at_str,AT_STR_LEN+MAX_AMT_AT_LEN,"\r\n+MEPCG:%s\r\nOK\r\n",pPtr);
+ send_rsp_str_to_farps(MODULE_ID_LOCKNET, at_str, strlen(at_str));
+ return 0;
+}
+
+int zCtrm_LocknetListGetNext()
+{
+ UINT32 retCode = EXT_ERROR;
+ UINT16 iList = 0;
+ UINT8 pPtr[MAX_AMT_AT_LEN] = {0};
+ CHAR at_str[AT_STR_LEN+MAX_AMT_AT_LEN] = {0};
+
+ T_zCtrm_LockListPara lockList = {0};
+ for(iList = 0; iList < LOCKNET_MAX_NUM - LOCKNET_FIRST_NUM; iList++)
+ {
+ memset(&lockList, 0, sizeof(lockList));//cov
+ //retCode = zDrvNand_Read(AMT_LOCKNET_LIST + (LOCKNET_FIRST_NUM+iList)*sizeof(lockList), sizeof(lockList), (UINT8 *)&lockList);
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_LIST + (LOCKNET_FIRST_NUM+iList)*sizeof(lockList), (UINT8 *)&lockList, sizeof(lockList));
+ if (EXT_SUCCESS != retCode )
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR\r\n");
+ send_rsp_str_to_farps(MODULE_ID_LOCKNET, at_str, strlen(at_str));
+ return 0;
+ }
+ if((lockList.mcc[0] == 0xFF)||(lockList.imsi6[0] == 0xFF)||(lockList.gid1[0] == 0xFF))
+ {
+ at_print(AT_ERR,"zCtrm_ExtLocknetListGetNext break iList:[%d]\n",iList);
+ break;
+ }
+ //cov
+ lockList.mcc[LIST_MCCMNC_LEN-1] = '\0';
+ lockList.mnc[LIST_MCCMNC_LEN-1] = '\0';
+ lockList.imsi6[LIST_IMSI_LEN-1] = '\0';
+ lockList.imsi7[LIST_IMSI_LEN-1] = '\0';
+ lockList.gid1[LIST_GID_LEN-1] = '\0';
+ lockList.gid2[LIST_GID_LEN-1] = '\0';
+ snprintf(pPtr+strlen(pPtr),sizeof(pPtr)-strlen(pPtr),"%s,%s,%s,%s,%s,%s;",
+ lockList.mcc,lockList.mnc,lockList.imsi6,lockList.imsi7,lockList.gid1,lockList.gid2);
+ }
+ snprintf(at_str,AT_STR_LEN+MAX_AMT_AT_LEN,"\r\n+MEPCG:%s\r\nOK\r\n",pPtr);
+ send_rsp_str_to_farps(MODULE_ID_LOCKNET, at_str, strlen(at_str));
+ return 0;
+}
+
+int zCtrm_LocknetListGetProc(MSG_BUF *msg)
+{
+ CHAR at_str[AT_STR_LEN] = {0};
+ char *at_paras = (char*)msg->aucDataBuf;
+ if(NULL != strstr(at_paras, "all"))
+ {
+ zCtrm_LocknetListGet();
+ }
+ else if(NULL != strstr(at_paras, "next"))
+ {
+ zCtrm_LocknetListGetNext();
+ }
+ else
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR\r\n");
+ send_rsp_str_to_farps(MODULE_ID_LOCKNET, at_str, strlen(at_str));
+ }
+ return 0;
+}
+
+//¶ÁÈ¡ËøÍø²ÎÊý¡¢½âËøÂ롢ǩÃû£¬ÅжÏÊÇ·ñ´æÔÚ
+static UINT32 zCtrm_SignExistAuthMutex(VOID)
+{
+ UINT32 retCode=EXT_ERROR;
+ T_zCtrm_LockListPara lockList = {0};
+ T_zCtrm_LockListPara lockListTmp = {0};
+ UINT8 keyBuf[KEY_LEN] = {0};
+ UINT8 signBuf[KEY_LEN] = {0};
+
+ //ËøÍø²ÎÊý
+ //retCode = zDrvNand_Read(AMT_LOCKNET_LIST, sizeof(lockList), (UINT8 *)&lockList);
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_LIST, (UINT8 *)&lockList, sizeof(lockList));
+ if (EXT_SUCCESS != retCode)
+ {
+ return READ_ERROR;
+ }
+ if((lockList.mcc[0] == 0xFF)||(lockList.imsi6[0] == 0xFF)||(lockList.gid1[0] == 0xFF))
+ {
+ return LOCKKEY_ISNULL;
+ }
+ if(memcmp(&lockList,&lockListTmp,sizeof(T_zCtrm_LockListPara)) == 0)
+ {
+ return LOCKKEY_ISNULL;//¹æ±Ünvrowall.binÈ«0µÄÎÊÌâ
+ }
+
+ //½âËøÂë
+ //retCode = zDrvNand_Read(AMT_LOCKNET_KEY, sizeof(keyBuf), keyBuf);
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_KEY, keyBuf, sizeof(keyBuf));
+ if (EXT_SUCCESS != retCode)
+ {
+ return READ_ERROR;
+ }
+ if(keyBuf[0] == 0xFF)
+ {
+ return LOCKKEY_ISNULL;
+ }
+
+ //Ç©Ãû
+ //retCode = zDrvNand_Read(AMT_LOCKNET_SIGN, sizeof(signBuf), signBuf);
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_SIGN, signBuf, sizeof(signBuf));
+ if (EXT_SUCCESS != retCode)
+ {
+ return READ_ERROR;
+ }
+ if(signBuf[0] == 0xFF)
+ {
+ return LOCKKEY_ISNULL;
+ }
+
+ return READ_SUCCESS;
+
+}
+
+static UINT32 zCtrm_SignAuth(VOID)
+{
+ UINT32 retCode = EXT_ERROR;
+ UINT8 signBuf[KEY_LEN] = {0};
+ UINT8 signHex128[KEY_LEN] = {0};
+ char signtext[LOCKNET_KEY_LEN*2+1] = {0};
+ char psDest[LOCKNET_KEY_LEN*2+1] = {0};
+
+ //Ç©Ãû
+ //retCode = zDrvNand_Read(AMT_LOCKNET_SIGN, sizeof(signBuf), signBuf);
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_SIGN, signBuf, sizeof(signBuf));
+ if (EXT_SUCCESS != retCode)
+ {
+ return RESULT_ERROR;
+ }
+
+ //¹«Ô¿½âÃÜ
+ retCode = zCtrm_RsaPublicEncryptProc(signBuf, signHex128);
+ if (EXT_SUCCESS != retCode)
+ {
+ return RESULT_ERROR;
+ }
+
+ zCtrm_Bytes2String(signHex128+KEY_LEN-LOCKNET_KEY_LEN, signtext, LOCKNET_KEY_LEN);
+
+ //ÕªÒªÓëÇ©Ãû ±È½Ï ÕªÒªÓù«Ô¿½âÃÜ
+ retCode=zCtrm_LocknetDigestMD5Hash(psDest);
+ if (EXT_SUCCESS != retCode)
+ {
+ return RESULT_ERROR;
+ }
+
+ at_print(AT_ERR,"zCtrm_SignAuth signtext=%s,psDest=%s!",signtext,psDest);
+ if(0 != strcasecmp(signtext,psDest))
+ {
+ return RESULT_LOCKED;
+ }
+ return RESULT_UNLOCKED;
+}
+
+static UINT32 zCtrm_KeyAuth(VOID)
+{
+ UINT32 retCode = EXT_ERROR;
+ UINT8 keyBuf[KEY_LEN] = {0};
+ UINT8 usrkeyBuf[LOCKNET_KEY_LEN] = {0};
+ UINT8 usrkeyBuf128[KEY_LEN] = {0};
+ UINT8 usrKeyText[KEY_LEN] = {0};
+
+ //½âËøÂë
+ //retCode = zDrvNand_Read(AMT_LOCKNET_KEY, sizeof(keyBuf), keyBuf);
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_KEY, keyBuf, sizeof(keyBuf));
+ if (EXT_SUCCESS != retCode || keyBuf[0] == 0xFF)
+ {
+ return RESULT_ERROR;
+ }
+
+ //Óû§½âËøÂë
+ //retCode = zDrvNand_Read(AMT_LOCKNET_USRKEY, sizeof(usrkeyBuf), usrkeyBuf);
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_USRKEY, usrkeyBuf, sizeof(usrkeyBuf));
+ if (EXT_SUCCESS != retCode || usrkeyBuf[0] == 0xFF)
+ {
+ return RESULT_LOCKED;
+ }
+
+ memcpy(usrkeyBuf128+KEY_LEN-LOCKNET_KEY_LEN, usrkeyBuf, LOCKNET_KEY_LEN);
+ retCode = zCtrm_RsaPublicEncryptProc(usrkeyBuf128, usrKeyText);
+ if (EXT_SUCCESS != retCode )
+ {
+ return RESULT_ERROR;
+ }
+
+ //Óû§½âËøÂëÓë½âËøÂë ±È½Ï ¼ÓÃܺó±È½Ï
+ if(memcmp(keyBuf,usrKeyText,KEY_LEN) != 0)
+ {
+ return RESULT_LOCKED;
+ }
+ return RESULT_UNLOCKED;
+}
+
+void zCtrm_DoSimAuth()
+{
+ char crsmrsp[256] = {0};
+ void *p[] = {crsmrsp};
+ UINT8 *pRes = NULL;
+ CHAR fileSize[5] = {0};
+ char at_str[AT_STR_LEN] = {0};
+ int ret = -1;
+
+ snprintf(at_str, AT_STR_LEN, "AT+CRSM=192,%ld,0,0,15,,\"3F007F20\"\r\n", IDENTIFIER_GID1);
+ ret = get_modem_info(at_str, "%s", p);
+ if (ret)
+ {
+ at_print(AT_ERR,"zCtrm_SignExistAuthMutex crsm error!\n");
+ simPara.fileLen = 0;
+ }
+ else
+ {
+ pRes = strstr(crsmrsp, "144,0,");//±íʾÕýÈ·¶ÁÈ¡
+ if(NULL != pRes)
+ {
+ strncpy(fileSize, pRes+strlen("144,0,")+4, 4);
+ simPara.fileLen = zCtrm_Atohex(fileSize[0])*4096 + zCtrm_Atohex(fileSize[1])*256 + zCtrm_Atohex(fileSize[2])*16 + zCtrm_Atohex(fileSize[3]);
+ at_print(AT_ERR,"crsm_ok_act, fileLen1 = %ld \n", simPara.fileLen);
+ }
+ else
+ {
+ simPara.fileLen = 0;
+ }
+ }
+ snprintf(at_str, AT_STR_LEN, "AT+CRSM=176,%ld,0,0,%ld\r\n", IDENTIFIER_GID1, simPara.fileLen);
+ ret = get_modem_info(at_str, "%s", p);
+ if (ret)
+ at_print(AT_ERR,"zCtrm_SignExistAuthMutex crsm error!\n");
+ else
+ {
+ pRes = strstr(crsmrsp, "144,0,");//±íʾÕýÈ·¶ÁÈ¡
+ if(NULL != pRes)
+ {
+ strncpy(simLockListPara.gid1, pRes+strlen("144,0,"), LIST_GID_LEN-1);
+ at_print(AT_ERR,"crsm_ok_act, gid1 = %s \n", simLockListPara.gid1);
+ }
+
+ }
+ snprintf(at_str, AT_STR_LEN, "AT+CRSM=192,%ld,0,0,15,,\"3F007F20\"", IDENTIFIER_GID2);
+ ret = get_modem_info(at_str, "%s", p);
+ if (ret)
+ {
+ at_print(AT_ERR,"zCtrm_SignExistAuthMutex crsm error!\n");
+ simPara.fileLen = 0;
+ }
+ else
+ {
+ pRes = strstr(crsmrsp, "144,0,");//±íʾÕýÈ·¶ÁÈ¡
+ if(NULL != pRes)
+ {
+ strncpy(fileSize, pRes+strlen("144,0,")+4, 4);
+ simPara.fileLen = zCtrm_Atohex(fileSize[0])*4096 + zCtrm_Atohex(fileSize[1])*256 + zCtrm_Atohex(fileSize[2])*16 + zCtrm_Atohex(fileSize[3]);
+ at_print(AT_ERR,"crsm_ok_act, fileLen2 = %ld \n", simPara.fileLen);
+ }
+ else
+ {
+ simPara.fileLen = 0;
+ }
+ }
+ snprintf(at_str, AT_STR_LEN, "AT+CRSM=176,%ld,0,0,%ld\r\n", IDENTIFIER_GID2, simPara.fileLen);
+ ret = get_modem_info(at_str, "%s", p);
+ if (ret)
+ at_print(AT_ERR,"zCtrm_SignExistAuthMutex crsm error!\n");
+ else
+ {
+ pRes = strstr(crsmrsp, "144,0,");//±íʾÕýÈ·¶ÁÈ¡
+ if(NULL != pRes)
+ {
+ strncpy(simLockListPara.gid2, pRes+strlen("144,0,"), LIST_GID_LEN-1);
+ at_print(AT_ERR,"crsm_ok_act, gid2 = %s \n", simLockListPara.gid2);
+ }
+ }
+ ret = get_modem_info("AT+CRSM=176,28589,0,0,4\r\n", "%s", p);
+ if (ret)
+ {
+ simPara.mncLen = 2;
+ at_print(AT_ERR,"crsm_err_act, mncLen = %d \n", simPara.mncLen);
+ }
+ else
+ {
+ pRes = strstr(crsmrsp, "144,0,");//±íʾÕýÈ·¶ÁÈ¡
+ if((NULL != pRes)&&(0 == strcmp("03", pRes+strlen("144,0,")+6))) //use 02 test
+ {
+ simPara.mncLen = 3;
+ }
+ else
+ {
+ simPara.mncLen = 2;
+ }
+ at_print(AT_ERR,"crsm_ok_act, mncLen = %d \n", simPara.mncLen);
+ }
+ return;
+}
+
+void zCtrm_DoUsimAuth()
+{
+ char crsmrsp[256] = {0};
+ void *p[] = {crsmrsp};
+ UINT8 *pRes = NULL;
+ CHAR fileSize[5] = {0};
+ int ret = -1;
+
+ ret = get_modem_info("AT+CRSM=176,28478,0,0,0\r\n", "%s", p);
+ if (ret)
+ at_print(AT_ERR,"cardmode_err_act zCtrm_USimAuth ERROR!\n");
+ else
+ {
+ pRes = strstr(crsmrsp, "144,0,");
+ if(NULL != pRes)
+ {
+ strncpy(simLockListPara.gid1, pRes+strlen("144,0,"), LIST_GID_LEN-1);
+ at_print(AT_ERR,"crsm_ok_act, gid1 = %s \n", simLockListPara.gid1);
+ }
+ }
+ ret = get_modem_info("AT+CRSM=176,28479,0,0,0\r\n", "%s", p);
+ if (ret)
+ at_print(AT_ERR,"cardmode_err_act zCtrm_USimAuth ERROR!\n");
+ else
+ {
+ pRes = strstr(crsmrsp, "144,0,");
+ if(NULL != pRes)
+ {
+ strncpy(simLockListPara.gid2, pRes+strlen("144,0,"), LIST_GID_LEN-1);
+ at_print(AT_ERR,"crsm_ok_act, gid2 = %s \n", simLockListPara.gid2);
+ }
+ }
+ ret = get_modem_info("AT+CRSM=176,28589,0,0,4\r\n", "%s", p);
+ if (ret)
+ {
+ simPara.mncLen = 2;
+ at_print(AT_ERR,"crsm_err_act, mncLen = %d \n", simPara.mncLen);
+ }
+ else
+ {
+ pRes = strstr(crsmrsp, "144,0,");
+ if((NULL != pRes)&&(0 == strcmp("03", pRes+strlen("144,0,")+6))) //use 02 test
+ {
+ simPara.mncLen = 3;
+ }
+ else
+ {
+ simPara.mncLen = 2;
+ }
+ at_print(AT_ERR,"crsm_ok_act, mncLen = %d \n", simPara.mncLen);
+ }
+ return;
+}
+
+VOID zCtrm_SIMPara2Auth(T_zCtrm_LockListPara *fromSim, T_zCtrm_SIMPara simPara)
+{
+ strncpy(fromSim->mcc,simPara.simImsi,3);
+ if (simPara.mncLen < sizeof(fromSim->mnc)) {
+ memset(fromSim->mnc,0,sizeof(fromSim->mnc));
+ snprintf(fromSim->mnc,simPara.mncLen+1,"%s",simPara.simImsi+3);
+ //strncpy(fromSim->mnc,simPara.simImsi+3,simPara.mncLen);
+ }
+ strncpy(fromSim->imsi6,simPara.simImsi+5,1);
+ strncpy(fromSim->imsi7,simPara.simImsi+6,1);
+}
+
+UINT32 zCtrm_AuthSIMPara(T_zCtrm_LockListPara *simPara)
+{
+ UINT32 retCode = EXT_ERROR;
+ UINT32 iNum = 0;
+
+ if(0 == strcmp("001",simPara->mcc) && 0 == strcmp("01",simPara->mnc))
+ //if(0 == strcmp("460",simPara.mcc) && 0 == strcmp("01",simPara.mnc))
+ {
+ at_print(AT_ERR,"sim ex\n");
+ return EXT_SUCCESS;
+ }
+
+ for(iNum = 0; iNum < LOCKNET_MAX_NUM; iNum++)
+ {
+ T_zCtrm_LockListPara lockList = {0};
+ //retCode = zDrvNand_Read(AMT_LOCKNET_LIST + iNum*sizeof(lockList), sizeof(lockList), (UINT8 *)&lockList);
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_LIST + iNum*sizeof(lockList), (UINT8 *)&lockList, sizeof(lockList));
+ if (EXT_SUCCESS != retCode )
+ {
+ at_print(AT_ERR,"zCtrm_AuthSIMPara:zDrvNand_Read error\n");
+ return EXT_ERROR;
+ }
+
+ if((lockList.mcc[0] == 0xFF)||(lockList.imsi6[0] == 0xFF)||(lockList.gid1[0] == 0xFF))
+ {
+ at_print(AT_ERR,"zCtrm_AuthSIMPara: lockList value error\n");
+ return EXT_ERROR;
+ }
+ //cov
+ lockList.mcc[LIST_MCCMNC_LEN-1] = '\0';
+ lockList.mnc[LIST_MCCMNC_LEN-1] = '\0';
+ lockList.imsi6[LIST_IMSI_LEN-1] = '\0';
+ lockList.imsi7[LIST_IMSI_LEN-1] = '\0';
+ if( (lockList.mcc[0] == '\0'||0 == strcmp(lockList.mcc,simPara->mcc))
+ &&(lockList.mnc[0] == '\0'||0 == strcmp(lockList.mnc,simPara->mnc))
+ &&(lockList.imsi6[0] == '\0'||0 == strcmp(lockList.imsi6,simPara->imsi6))
+ &&(lockList.imsi7[0] == '\0'||0 == strcmp(lockList.imsi7,simPara->imsi7))
+ &&(lockList.gid1[0] == '\0'||0 == zCtrm_Strnicmp(lockList.gid1,simPara->gid1,USED_GID_LEN))
+ &&(lockList.gid2[0] == '\0'||0 == zCtrm_Strnicmp(lockList.gid2,simPara->gid2,USED_GID_LEN)) )
+ {
+ at_print(AT_ERR,"sim checked\n");
+ return EXT_SUCCESS;
+ }
+ }
+
+ at_print(AT_ERR,"zCtrm_AuthSIMPara: other error\n");
+ return EXT_ERROR;
+}
+
+static UINT32 zCtrm_SimAuth()
+{
+ int ret = -1;
+ int cardmode = 0;
+ void *p1[] = {&cardmode};
+ char imsi[MAX_IMSI_LEN] = {0};
+ void *p2[] = {imsi};
+
+ ret = get_modem_info("AT^CARDMODE\r\n", "%d", p1);
+ if (ret) {
+ simPara.cardMode = CARDMODE_UNKNOW;
+ at_print(AT_ERR,"cardmode_err_act zCtrm_SimAuth ERROR!\n");
+ return RESULT_ERROR;
+ }
+ if(1 == cardmode)
+ {
+ simPara.cardMode = CARDMODE_SIM;
+ zCtrm_DoSimAuth();
+ }
+ else if(2 == cardmode)
+ {
+ simPara.cardMode = CARDMODE_USIM;
+ zCtrm_DoUsimAuth();
+ }
+ else
+ return RESULT_ERROR;
+ ret = get_modem_info("AT+CIMI\r\n", "%s", p2);
+ if (ret)
+ {
+ at_print(AT_ERR,"cimi_err_act zCtrm_SimAuth ERROR!\n");
+ return RESULT_ERROR;
+ }
+ else
+ {
+ strncpy(simPara.simImsi,imsi,sizeof(simPara.simImsi)-1);
+ if(*(simPara.simImsi) == '\0')
+ {
+ at_print(AT_ERR,"cimi_ok_act zCtrm_SimAuth ERROR!\n");
+ return RESULT_ERROR;
+ }
+ zCtrm_SIMPara2Auth(&simLockListPara, simPara);
+ ret = zCtrm_AuthSIMPara(&simLockListPara);
+ if (EXT_SUCCESS != ret)
+ {
+ ret = get_modem_info("AT+CFUN=4;+ZSCHPLMN=0\r\n", NULL, NULL);
+ if (ret)
+ {
+ at_print(AT_ERR,"zCtrm_SimAuth ZSCHPLMN0 error!\n");
+ }
+ return RESULT_LOCKED;
+ }
+ else
+ {
+ ret = get_modem_info("AT+ZSCHPLMN=1\r\n", NULL, NULL);
+ if (ret)
+ {
+ at_print(AT_ERR,"zCtrm_SimAuth ZSCHPLMN1 error!\n");
+ }
+ return RESULT_UNLOCKED;
+ }
+ }
+
+}
+
+int zCtrm_makeLocknetAuth(MSG_BUF *msg)
+{
+ UINT32 readCode = READ_ERROR;//¶ÁÈ¡ËøÍø²ÎÊý¡¢½âËøÂ롢ǩÃûÊÇ·ñ´æÔÚ
+ UINT32 result = RESULT_ERROR;//ÿһ²½µÄÅжϽá¹û
+ char at_str[AT_STR_LEN] = {0};
+ int ret = -1;
+
+ at_print(AT_ERR,"zCtrm_ExtLocknetAuth,status = %d\n",g_Sec_Status);
+ if(g_Sec_Status != ENCRYPT_LOCK && g_Sec_Status != ENCRYPT_UNLOCK_CORRECT)
+ {
+ at_print(AT_ERR,"zCtrm_LocknetAuth, g_Sec_Status:%d\n",g_Sec_Status);
+
+ //ËøÍø²ÎÊý¡¢½âËøÂ롢ǩÃûÊÇ·ñ´æÔÚ
+ readCode = zCtrm_SignExistAuthMutex();
+ if(readCode == READ_ERROR)
+ {
+ g_Sec_Status = ENCRYPT_ERROR;
+ at_print(AT_ERR,"zCtrm_SignExistAuthMutex ERROR!\n");
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:149\r\n");
+ goto end;
+ }
+ else if(readCode == LOCKKEY_ISNULL)
+ {
+ ret = get_modem_info("AT+ZSCHPLMN=1\r\n", NULL, NULL);
+ if (ret) {
+ at_print(AT_ERR,"zCtrm_SignExistAuthMutex zschplmn1 error!\n");
+ }
+ g_Sec_Status = ENCRYPT_UNLOCK_CORRECT;
+ at_print(AT_ERR,"zCtrm_SignExistAuthMutex UNLOCK!\n");
+ snprintf(at_str,AT_STR_LEN,"\r\nOK\r\n");
+ goto end;
+ }
+ //²ÎÊý´æÔÚ£¬½øÒ»²½ÅжÏ
+ else
+ {
+ //ÅжÏÕªÒªÓëÇ©ÃûÊÇ·ñÒ»Ö£¬Ç©ÃûÐèÒªÓù«Ô¿½âÃÜ
+ result = zCtrm_SignAuth();
+ if(result == RESULT_ERROR)
+ {
+ g_Sec_Status = ENCRYPT_ERROR;
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:149\r\n");
+ goto end;
+ }
+ else if(result == RESULT_LOCKED)
+ {
+ snprintf(at_str,AT_STR_LEN,"AT+CFUN=4;+ZSCHPLMN=0\r\n");
+ ret = get_modem_info(at_str, NULL, NULL);
+ if (ret) {
+ at_print(AT_ERR,"zCtrm_SignExistAuthMutex zschplmn0 error!\n");
+ }
+ g_Sec_Status = ENCRYPT_LOCK;
+ at_print(AT_ERR,"zCtrm_SignAuth LOCK!\n");
+ snprintf(at_str,AT_STR_LEN,"\r\nOK\r\n");
+ goto end;
+ }
+ //½øÒ»²½ÅжÏ
+ else
+ {
+ //ÅжϽâËøÂëÓëÓû§½âËøÂëÊÇ·ñÒ»Ö£¬Óû§½âËøÂëÐèÒªÓù«Ô¿¼ÓÃÜ
+ //½öµ±Óû§½âËøÂë²»´æÔÚ»òÕßÓû§½âËøÂëÓë½âËøÂë²»Ò»Ñùʱ£¬½øÐÐsim¿¨ÅжÏ
+ result = zCtrm_KeyAuth();
+ if(result == RESULT_ERROR)
+ {
+ g_Sec_Status = ENCRYPT_ERROR;
+ at_print(AT_ERR,"zCtrm_KeyAuth ERROR!\n");
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:149\r\n");
+ goto end;
+ }
+ else if(result == RESULT_UNLOCKED)
+ {
+ ret = get_modem_info("AT+ZSCHPLMN=1\r\n", NULL, NULL);
+ if (ret) {
+ at_print(AT_ERR,"zCtrm_SignExistAuthMutex zschplmn1 error!\n");
+ }
+ g_Sec_Status = ENCRYPT_UNLOCK_CORRECT;
+ at_print(AT_ERR,"zCtrm_KeyAuth UNLOCK!\n");
+ snprintf(at_str,AT_STR_LEN,"\r\nOK\r\n");
+ goto end;
+ }
+ //½øÒ»²½ÅжÏ
+ else
+ {
+ result = zCtrm_SimAuth();
+ if(RESULT_ERROR == result)
+ {
+ g_Sec_Status = ENCRYPT_ERROR;
+ at_print(AT_ERR,"zCtrm_SimAuth ERROR!\n");
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:149\r\n");
+ goto end;
+ }
+ else if(RESULT_LOCKED == result)
+ {
+ g_Sec_Status = ENCRYPT_LOCK;
+ snprintf(at_str,AT_STR_LEN,"\r\nOK\r\n");
+ goto end;
+ }
+ else
+ {
+ g_Sec_Status = ENCRYPT_UNLOCK_CORRECT;
+ snprintf(at_str,AT_STR_LEN,"\r\nOK\r\n");
+ goto end;
+ }
+ }
+
+ }
+ }
+ /* cov2
+ ret = get_modem_info("AT+ZSCHPLMN=1\r\n", NULL, NULL);
+ if (ret) {
+ at_print(AT_ERR,"zCtrm_SignExistAuthMutex zschplmn1 error!\n");
+ }
+ g_Sec_Status = ENCRYPT_UNLOCK_CORRECT;
+ snprintf(at_str,AT_STR_LEN,"\r\nOK\r\n");
+ goto end;
+ */
+ }
+ snprintf(at_str,AT_STR_LEN,"\r\nOK\r\n");
+ goto end;
+end:
+ if(1 == sendflag)
+ {
+ send_rsp_str_to_farps(MODULE_ID_LOCKNET, at_str, strlen(at_str));//Èç¹ûÊÇzurdy´¥·¢µÄËøÍøÁ÷³Ì£¬²»ÐèÒªÏò´®¿Ú·¢·µ»ØÖµ
+ sendflag = 0;
+ }
+ return 0;
+}
+
+static UINT32 zCtrm_UnlockTimesCheck(UINT32 *curTimes)
+{
+ UINT32 retCode = EXT_ERROR;
+ UINT32 times = 0;
+ UINT32 maxTimes = 0;
+ T_zCtrm_LockLevel lockState = NEVER_LOCKED;
+
+ //retCode = zDrvNand_Read(AMT_LOCKNET_BASE, sizeof(lockState),(UINT8 *)&lockState);
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_BASE,(UINT8 *)&lockState, sizeof(lockState));
+ at_print(AT_ERR,"zCtrm_UnlockCodeCheck lockState=%d,retCode=%d!\n",lockState,retCode);
+ if (EXT_SUCCESS != retCode || lockState != LOCKED)
+ {
+ return EXT_ERROR;
+ }
+
+
+ //retCode = zDrvNand_Read(AMT_LOCKNET_TIMES, sizeof(times),(UINT8 *)×);
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_TIMES,(UINT8 *)×, sizeof(times));
+ at_print(AT_ERR,"zCtrm_UnlockCodeCheck times=%d,retCode=%d!\n",times,retCode);
+ if (EXT_SUCCESS != retCode)
+ {
+ return EXT_ERROR;
+ }
+
+ maxTimes = zCtrm_GetUnlockMaxTime();
+ if(times > 0 && times <= maxTimes)
+ {
+ *curTimes = times;
+ return EXT_SUCCESS;
+ }
+
+ return EXT_ERROR;
+}
+
+//Óû§ÊäÈëµÄ½âËøÂ룬ÐèÒªÓù«Ô¿¼ÓÃܺóÔÙÓë´æÈëROÖеĽâËøÂë±È½Ï¡£
+//(ROÖнâËøÂë128λ)
+static UINT32 zCtrm_UnlockCodeCheck(UINT8 *keyBuf,UINT16 keyLen)
+{
+ UINT32 retCode = EXT_ERROR;
+ UINT8 lockkey[KEY_LEN] = {0};
+ UINT8 keyBufText[KEY_LEN] = {0};//Óû§ÊäÈë½âËøÂë¼ÓÃܺó×Ö·û
+ UINT8 test1[KEY_LEN*2+1]={0};
+ UINT8 test2[KEY_LEN*2+1]={0};
+ UINT8 keyBuf128[KEY_LEN]={0};
+
+
+ //retCode = zDrvNand_Read(AMT_LOCKNET_KEY, sizeof(lockkey), lockkey);
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_KEY,lockkey, sizeof(lockkey));
+ zCtrm_Bytes2String(lockkey, test1, KEY_LEN);
+ at_print(AT_ERR,"zCtrm_UnlockCodeCheck lockkey=%s,len=%d!\n",test1,strlen(test1));
+ if (EXT_SUCCESS != retCode)
+ {
+ return EXT_ERROR;
+ }
+
+
+ memcpy(keyBuf128+KEY_LEN-LOCKNET_KEY_LEN, keyBuf, LOCKNET_KEY_LEN);
+ retCode = zCtrm_RsaPublicEncryptProc(keyBuf128, keyBufText);
+ zCtrm_Bytes2String(keyBufText, test2, KEY_LEN);
+ at_print(AT_ERR,"zCtrm_UnlockCodeCheck keyBufText=%s,len=%d!\n",test2,strlen(test2));
+ if (EXT_SUCCESS != retCode )
+ {
+ return EXT_ERROR;
+ }
+
+ if(memcmp(keyBufText,lockkey,keyLen) != 0)
+ {
+ return EXT_ERROR;
+ }
+
+ return EXT_SUCCESS;
+}
+
+static VOID zCtrm_UnlockTimesUpdate(UINT32 curTimes)
+{
+ UINT32 retCode = EXT_ERROR;
+ UINT32 maxTimes = 0;
+
+ maxTimes = zCtrm_GetUnlockMaxTime();
+ if(curTimes > 0 && curTimes <= maxTimes)
+ {
+ curTimes = curTimes - 1;
+ }
+ else
+ {
+ curTimes = 0;
+ }
+
+ cpnv_ChangeNvRoAttr(1);
+ //retCode = zDrvNand_Program(AMT_LOCKNET_TIMES, sizeof(curTimes),(UINT8 *)&curTimes);
+ retCode = cpnv_NvItemWriteNvro(AMT_LOCKNET_TIMES, (UINT8 *)&curTimes, sizeof(curTimes));
+ if (EXT_SUCCESS != retCode)
+ {
+ //retCode = zDrvNand_Program(AMT_LOCKNET_TIMES, sizeof(curTimes),(UINT8 *)&curTimes);
+ retCode = cpnv_NvItemWriteNvro(AMT_LOCKNET_TIMES, (UINT8 *)&curTimes, sizeof(curTimes));
+ at_print(AT_ERR,"zCtrm_UnlockTimesUpdate: %ld\n",retCode);
+ }
+ cpnv_FsGcWait(FS_NVROFS);
+ cpnv_ChangeNvRoAttr(0);
+ at_print(AT_ERR,"zCtrm_UnlockTimesUpdate cur: %ld\n",curTimes);
+}
+
+static UINT32 zCtrm_UnlockNandSet(UINT8 *keyBuf,UINT16 len)
+{
+ T_zCtrm_LockLevel lockState = ALREADY_UNLOCKED;
+ T_zCtrm_LockLevel lockState_out = ALREADY_UNLOCKED;
+ UINT32 times = zCtrm_GetUnlockMaxTime();
+ UINT32 retCode =EXT_ERROR;
+
+ cpnv_ChangeNvRoAttr(1);
+ //retCode = zDrvNand_Program(AMT_LOCKNET_TIMES, sizeof(times),(UINT8 *)×);
+ retCode = cpnv_NvItemWriteNvro(AMT_LOCKNET_TIMES, (UINT8 *)×, sizeof(times));
+ at_print(AT_ERR,"zCtrm_UnlockNandSet len=%d,times=%d!\n",sizeof(times),times);
+ if (EXT_SUCCESS != retCode)
+ {
+ cpnv_ChangeNvRoAttr(0);
+ return EXT_ERROR;
+ }
+
+ //retCode = zDrvNand_Program(AMT_LOCKNET_USRKEY, len,keyBuf);
+ retCode = cpnv_NvItemWriteNvro(AMT_LOCKNET_USRKEY, keyBuf, len);
+ at_print(AT_ERR,"zCtrm_UnlockNandSet len=%d,keyBuf=%s!\n",len,keyBuf);
+ if (EXT_SUCCESS != retCode)
+ {
+ cpnv_ChangeNvRoAttr(0);
+ return EXT_ERROR;
+ }
+
+ //retCode = zDrvNand_Program(AMT_LOCKNET_BASE, sizeof(lockState),(UINT8 *)&lockState);
+ retCode = cpnv_NvItemWriteNvro(AMT_LOCKNET_BASE, (UINT8 *)&lockState, sizeof(lockState));
+ at_print(AT_ERR,"zCtrm_UnlockNandSet len=%d,lockstate=%d!\n",sizeof(lockState),lockState);
+ if (EXT_SUCCESS != retCode)
+ {
+ cpnv_ChangeNvRoAttr(0);
+ return EXT_ERROR;
+ }
+
+ //zDrvNand_Read(AMT_LOCKNET_BASE, sizeof(lockState_out),(UINT8 *)&lockState_out);
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_BASE,(UINT8 *)&lockState_out, sizeof(lockState_out));
+ at_print(AT_ERR,"zCtrm_UnlockNandSet len=%d,lockState_out=%d!\n",sizeof(lockState_out),lockState_out);
+ cpnv_FsGcWait(FS_NVROFS);
+ cpnv_ChangeNvRoAttr(0);
+
+ return EXT_SUCCESS;
+}
+
+int zCtrm_LocknetUnlock(MSG_BUF *msg)
+{
+ UINT32 retCode = EXT_ERROR;
+ UINT32 retryCount = 0;
+ UINT16 keyLen = 0;
+ MSG_BUF *p_msg = (MSG_BUF *)msg;
+ UINT8 keyBuf[LOCKNET_KEY_LEN+1] = {0};
+ char at_str[AT_STR_LEN] = {0};
+ int ret = -1;
+
+ at_print(AT_ERR,"zCtrm_LocknetUnlock\n");
+ retCode = zCtrm_UnlockTimesCheck(&retryCount);
+ if (EXT_SUCCESS != retCode )
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:3\r\n");
+ goto end;
+ }
+ at_print(AT_ERR,"zCtrm_LocknetUnlock cur: %ld\n",retryCount);
+ keyLen = p_msg->usDataLen;
+ if (keyLen != LOCKNET_KEY_LEN)
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:6004\r\n");
+ goto end;
+ }
+ memcpy(keyBuf,p_msg->aucDataBuf,keyLen);
+ at_print(AT_ERR,"zCtrm_ExtLocknetUnlock keyBuf=%s!\n",keyBuf);
+
+ retCode = zCtrm_UnlockCodeCheck(keyBuf,keyLen);
+ if (EXT_SUCCESS != retCode )
+ {
+ zCtrm_UnlockTimesUpdate(retryCount);
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:6004\r\n");
+ goto end;
+ }
+
+ //Ã÷ÎÄ´æÈëÓû§ÊäÈëµÄ½âËøÂë(16λ×Ö·û)
+ retCode = zCtrm_UnlockNandSet(keyBuf,keyLen);
+ if (EXT_SUCCESS != retCode )
+ {
+ zCtrm_UnlockTimesUpdate(retryCount);
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:6004\r\n");
+ goto end;
+ }
+ ret = get_modem_info("AT+ZSCHPLMN=1\r\n", NULL, NULL);
+ if (ret) {
+ at_print(AT_ERR,"zCtrm_LocknetUnlock zschplmn1 error!\n");
+ }
+ g_Sec_Status = ENCRYPT_UNLOCK_CORRECT;
+ at_print(AT_ERR,"zCtrm_UnlockModemSet\n");
+ snprintf(at_str,AT_STR_LEN,"\r\nOK\r\n");
+ goto end;
+ end:
+ send_rsp_str_to_farps(MODULE_ID_LOCKNET, at_str, strlen(at_str));
+ return 0;
+}
+
+static UINT32 zCtrm_UnlockTimesGet(UINT32 *curTimes)
+{
+ UINT32 retCode = EXT_ERROR;
+ UINT32 times = 0;
+ UINT32 maxTimes = 0;
+ T_zCtrm_LockLevel lockState = NEVER_LOCKED;
+
+ //retCode = zDrvNand_Read(AMT_LOCKNET_BASE, sizeof(lockState),(UINT8 *)&lockState);
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_BASE,(UINT8 *)&lockState, sizeof(lockState));
+ at_print(AT_ERR,"zCtrm_UnlockTimesGet lockState=%d,retCode=%d!\n",lockState,retCode);
+ if (EXT_SUCCESS != retCode || lockState != LOCKED)
+ {
+ return EXT_ERROR;
+ }
+
+
+ //retCode = zDrvNand_Read(AMT_LOCKNET_TIMES, sizeof(times),(UINT8 *)×);
+ retCode = cpnv_NvItemRead(AMT_LOCKNET_TIMES,(UINT8 *)×, sizeof(times));
+ at_print(AT_ERR,"zCtrm_UnlockTimesGet times=%d,retCode=%d!\n",times,retCode);
+ if (EXT_SUCCESS != retCode)
+ {
+ return EXT_ERROR;
+ }
+
+ maxTimes = zCtrm_GetUnlockMaxTime();
+ if(times <= maxTimes)//klocwork
+ {
+ *curTimes = times;
+ return EXT_SUCCESS;
+ }
+
+ return EXT_ERROR;
+}
+
+int zCtrm_LocknetUnlockTimes(MSG_BUF *msg)
+{
+ UINT32 retCode = EXT_ERROR;
+ UINT32 retryCount = 0;
+ UINT8 pStr[4] = {0};
+ char at_str[AT_STR_LEN] = {0};
+
+ retCode = zCtrm_UnlockTimesGet(&retryCount);
+ if (EXT_SUCCESS != retCode )
+ {
+ snprintf(at_str,AT_STR_LEN,"\r\n+CME ERROR:3\r\n");
+ goto end;
+ }
+ snprintf(at_str,AT_STR_LEN,"\r\n+ZNCK:%d\r\nOK\r\n",retryCount);
+ goto end;
+end:
+ send_rsp_str_to_farps(MODULE_ID_LOCKNET, at_str, strlen(at_str));
+ return 0;
+
+}
+
+int zCtrm_LocknetStatus(MSG_BUF *msg)
+{
+ T_zCtrm_SecItems secItems = NO_ACTION;
+ char at_str[AT_STR_LEN] = {0};
+
+ if(g_Sec_Status == ENCRYPT_LOCK)
+ {
+ secItems = NET_LOCK;
+ }
+ snprintf(at_str,AT_STR_LEN,"\r\n+ZSEC:%d,%d\r\nOK\r\n",g_Sec_Status,secItems);
+ send_rsp_str_to_farps(MODULE_ID_LOCKNET, at_str, strlen(at_str));
+ return 0;
+}
+