[Feature][Modem]Update MTK MODEM V1.6 baseline version: MOLY.NR15.R3.MD700.IVT.MP1MR3.MP.V1.6

MTK modem version: MT2735_IVT_MOLY.NR15.R3.MD700.IVT.MP1MR3.MP.V1.6.tar.gz
RF  modem version: NA

Change-Id: I45a4c2752fa9d1a618beacd5d40737fb39ab64fb
diff --git a/mcu/driver/che/include/aes.h b/mcu/driver/che/include/aes.h
new file mode 100644
index 0000000..a21d6cf
--- /dev/null
+++ b/mcu/driver/che/include/aes.h
@@ -0,0 +1,203 @@
+/* Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi> and contributors
+ * All Rights Reserved.
+ * 
+ * This program is dual-licensed under both the GPL version 2 and BSD
+ * license. Either license may be used at your option.
+ * 
+ * 
+ * 
+ * License
+ * -------
+ * 
+ * GPL v2:
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ * 
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * (this copy of the license is in COPYING file)
+ * 
+ * 
+ * Alternatively, this software may be distributed, used, and modified
+ * under the terms of BSD license:
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * 3. Neither the name(s) of the above-listed copyright holder(s) nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *    aes.h
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   aes software function.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+#ifndef __AES_H__
+#define __AES_H__
+
+#include "kal_general_types.h"
+
+#if defined(_MSC_VER)
+   #define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+   #define GETU32(p) SWAP(*((u32 *)(p)))
+   #define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
+#else
+   #define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] <<  8) ^ ((u32)(pt)[3]))
+   #define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >>  8); (ct)[3] = (u8)(st); }
+#endif
+
+typedef unsigned long u32;
+typedef unsigned short u16;
+typedef unsigned char u8;
+
+#define MAXKC   (256/32)
+#define MAXKB   (256/8)
+#define MAXNR   14
+
+
+#undef FULL_UNROLL
+
+
+
+#define AES_ENCRYPT	1
+#define AES_DECRYPT	0
+
+
+
+#define AES_MAXNR 14
+#define AES_BLOCK_SIZE 16
+
+struct aes_key_st {
+    unsigned long rd_key[4 *(AES_MAXNR + 1)];
+    int rounds;
+};
+typedef struct aes_key_st AES_KEY;
+
+kal_int32 CHE_AES_block_encrypt(kal_uint8 *ivec, AES_KEY *cipher, kal_uint8 *input, kal_uint32 uInputLen, kal_uint8 *outBuffer, kal_bool first_flag, kal_uint8 *orgIV);
+
+kal_int32 CHE_AES_block_decrypt(kal_uint8 *ivec, AES_KEY *cipher, kal_uint8 *input, kal_uint32 uInputLen, kal_uint8 *outBuffer, kal_bool first_flag, kal_uint8 *orgIV);
+
+
+void CHE_AES_unit_encrypt(const kal_uint32 rk[], kal_int32 Nr, const kal_uint8 pt[16], kal_uint8 ct[16]);
+
+void CHE_AES_unit_decrypt(const kal_uint32 rk[], int Nr, const kal_uint8 ct[16], kal_uint8 pt[16]);
+
+
+void CHE_AES_unit_encrypt(const kal_uint32 rk[], kal_int32 Nr, const kal_uint8 pt[16], kal_uint8 ct[16]);
+
+void CHE_AES_unit_decrypt(const kal_uint32 rk[], int Nr, const kal_uint8 ct[16], kal_uint8 pt[16]);
+
+
+kal_int32 CHE_AES_ctr_encrypt( unsigned char *nonce, AES_KEY *key, unsigned char *data, unsigned long data_len, unsigned char *output, kal_bool first_flag, kal_uint8 *orgIV, void *aes_param);
+
+kal_int32 CHE_AES_ctr_decrypt( unsigned char *nonce, AES_KEY *key, unsigned char *data, unsigned long data_len, unsigned char *output, kal_bool first_flag, kal_uint8 *orgIV, void *aes_param);
+
+kal_int32 CHE_AES_f8_encrypt( unsigned char *IV, AES_KEY *key, unsigned char *data, unsigned long data_len, unsigned char *output, kal_bool first_flag);
+
+kal_int32 CHE_AES_f8_decrypt( unsigned char *IV, AES_KEY *key, unsigned char *data, unsigned long data_len, unsigned char *output, kal_bool first_flag);
+
+kal_int32 CHE_AES_setup_enc_key(kal_uint32 rk[], const kal_uint8 *cipherKey, kal_int32 keyBits);
+//kal_int32 CHE_AES_ctr_decrypt( unsigned char *nonce, AES_KEY *key, unsigned char *data, unsigned long data_len, unsigned char *output, kal_bool first_flag, kal_uint8 *orgIV);
+kal_int32 CHE_AES_setup_dec_key(kal_uint32 rk[], const kal_uint8 cipherKey[], kal_int32 keyBits);
+int CHE_AES_WRAP(AES_KEY *key, kal_int32 n, const kal_uint8 *plain, kal_uint8 *cipher);
+int CHE_AES_UNWRAP(AES_KEY *key, kal_int32 n, const kal_uint8 *cipher, kal_uint8 *plain);
+#endif /* __AES_H__ */
diff --git a/mcu/driver/che/include/base64.h b/mcu/driver/che/include/base64.h
new file mode 100644
index 0000000..2915796
--- /dev/null
+++ b/mcu/driver/che/include/base64.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* ====================================================================
+ * Copyright (c) 1995-1999 The Apache Group.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the Apache Group
+ *    for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * 4. The names "Apache Server" and "Apache Group" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the Apache Group
+ *    for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Group and was originally based
+ * on public domain software written at the National Center for
+ * Supercomputing Applications, University of Illinois, Urbana-Champaign.
+ * For more information on the Apache Group and the Apache HTTP server
+ * project, please see <http://www.apache.org/>.
+ *
+ */
+
+
+
+#ifndef _BASE64_H_
+#define _BASE64_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int Base64encode_len(int len);
+int Base64encode(char * coded_dst, const char *plain_src,int len_plain_src);
+
+int Base64decode_len(const char * coded_src);
+int Base64decode(char * plain_dst, const char *coded_src);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_BASE64_H_
diff --git a/mcu/driver/che/include/bignum.h b/mcu/driver/che/include/bignum.h
new file mode 100644
index 0000000..4b2af6d
--- /dev/null
+++ b/mcu/driver/che/include/bignum.h
@@ -0,0 +1,409 @@
+/**
+ * \file bignum.h
+ */
+#ifndef XYSSL_BIGNUM_H
+#define XYSSL_BIGNUM_H
+
+#include <stdio.h>
+
+#define XYSSL_ERR_MPI_FILE_IO_ERROR                     -0x0002
+#define XYSSL_ERR_MPI_BAD_INPUT_DATA                    -0x0004
+#define XYSSL_ERR_MPI_INVALID_CHARACTER                 -0x0006
+#define XYSSL_ERR_MPI_BUFFER_TOO_SMALL                  -0x0008
+#define XYSSL_ERR_MPI_NEGATIVE_VALUE                    -0x000A
+#define XYSSL_ERR_MPI_DIVISION_BY_ZERO                  -0x000C
+#define XYSSL_ERR_MPI_NOT_ACCEPTABLE                    -0x000E
+
+#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup
+
+/*
+ * Define the base integer type, architecture-wise
+ */
+#if defined(XYSSL_HAVE_INT8)
+typedef unsigned char  t_int;
+typedef unsigned short t_dbl;
+#else
+#if defined(XYSSL_HAVE_INT16)
+typedef unsigned short t_int;
+typedef unsigned long  t_dbl;
+#else
+  typedef unsigned long t_int;
+  #if defined(_MSC_VER) && defined(_M_IX86)
+  typedef unsigned __int64 t_dbl;
+  #else
+    #if defined(__amd64__) || defined(__x86_64__)    || \
+        defined(__ppc64__) || defined(__powerpc64__) || \
+        defined(__ia64__)  || defined(__alpha__)
+    typedef unsigned int t_dbl __attribute__((mode(TI)));
+    #else
+    typedef unsigned long long t_dbl;
+    #endif
+  #endif
+#endif
+#endif
+
+/**
+ * \brief          MPI structure
+ */
+typedef struct
+{
+    int s;              /*!<  integer sign      */
+    int n;              /*!<  total # of limbs  */
+    t_int *p;           /*!<  pointer to limbs  */
+}
+mpi;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          Initialize one or more mpi
+ */
+void che_mpi_init( mpi *X, ... );
+
+/**
+ * \brief          Unallocate one or more mpi
+ */
+void che_mpi_free( mpi *X, ... );
+
+/**
+ * \brief          Enlarge to the specified number of limbs
+ *
+ * \return         0 if successful,
+ *                 1 if memory allocation failed
+ */
+int che_mpi_grow( mpi *X, int nblimbs );
+
+/**
+ * \brief          Copy the contents of Y into X
+ *
+ * \return         0 if successful,
+ *                 1 if memory allocation failed
+ */
+int che_mpi_copy( mpi *X, mpi *Y );
+
+/**
+ * \brief          Swap the contents of X and Y
+ */
+void che_mpi_swap( mpi *X, mpi *Y );
+
+/**
+ * \brief          Set value from integer
+ *
+ * \return         0 if successful,
+ *                 1 if memory allocation failed
+ */
+int che_mpi_lset( mpi *X, int z );
+
+/**
+ * \brief          Return the number of least significant bits
+ */
+int che_mpi_lsb( mpi *X );
+
+/**
+ * \brief          Return the number of most significant bits
+ */
+int che_mpi_msb( mpi *X );
+
+/**
+ * \brief          Return the total size in bytes
+ */
+int che_mpi_size( mpi *X );
+
+/**
+ * \brief          Import from an ASCII string
+ *
+ * \param X        destination mpi
+ * \param radix    input numeric base
+ * \param s        null-terminated string buffer
+ *
+ * \return         0 if successful, or an XYSSL_ERR_MPI_XXX error code
+ */
+int che_mpi_read_string( mpi *X, int radix, char *s );
+
+int che_mpi_read_string_ex( mpi *X, char *s, int radix, int s_len );
+int che_mpi_read( mpi *X, unsigned char *s_tmp, int radix, int s_len );
+
+/**
+ * \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 XYSSL_ERR_MPI_XXX error code
+ *
+ * \note           Call this function with *slen = 0 to obtain the
+ *                 minimum required buffer size in *slen.
+ */
+int che_mpi_write_string( mpi *X, int radix, char *s, int *slen );
+
+/**
+ * \brief          Read X from an opened file
+ *
+ * \param X        destination mpi
+ * \param radix    input numeric base
+ * \param fin      input file handle
+ *
+ * \return         0 if successful, or an XYSSL_ERR_MPI_XXX error code
+ */
+int che_mpi_read_file( mpi *X, int radix, FILE *fin );
+
+/**
+ * \brief          Write X into an opened file, or stdout
+ *
+ * \param p        prefix, can be NULL
+ * \param X        source mpi
+ * \param radix    output numeric base
+ * \param fout     output file handle
+ *
+ * \return         0 if successful, or an XYSSL_ERR_MPI_XXX error code
+ *
+ * \note           Set fout == NULL to print X on the console.
+ */
+int che_mpi_write_file( char *p, mpi *X, int radix, FILE *fout );
+
+/**
+ * \brief          Import X from unsigned binary data, big endian
+ *
+ * \param X        destination mpi
+ * \param buf      input buffer
+ * \param buflen   input buffer size
+ *
+ * \return         0 if successful,
+ *                 1 if memory allocation failed
+ */
+int che_mpi_read_binary( mpi *X, unsigned char *buf, int buflen );
+
+/**
+ * \brief          Export X into unsigned binary data, big endian
+ *
+ * \param X        source mpi
+ * \param buf      output buffer
+ * \param buflen   output buffer size
+ *
+ * \return         0 if successful,
+ *                 XYSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
+ *
+ * \note           Call this function with *buflen = 0 to obtain the
+ *                 minimum required buffer size in *buflen.
+ */
+int che_mpi_write_binary( mpi *X, unsigned char *buf, int buflen );
+
+/**
+ * \brief          Left-shift: X <<= count
+ *
+ * \return         0 if successful,
+ *                 1 if memory allocation failed
+ */
+int che_mpi_shift_l( mpi *X, int count );
+
+/**
+ * \brief          Right-shift: X >>= count
+ *
+ * \return         0 if successful,
+ *                 1 if memory allocation failed
+ */
+int che_mpi_shift_r( mpi *X, int count );
+
+/**
+ * \brief          Compare unsigned values
+ *
+ * \return         1 if |X| is greater than |Y|,
+ *                -1 if |X| is lesser  than |Y| or
+ *                 0 if |X| is equal to |Y|
+ */
+int che_mpi_cmp_abs( mpi *X, mpi *Y );
+
+/**
+ * \brief          Compare signed values
+ *
+ * \return         1 if X is greater than Y,
+ *                -1 if X is lesser  than Y or
+ *                 0 if X is equal to Y
+ */
+int che_mpi_cmp_mpi( mpi *X, mpi *Y );
+
+/**
+ * \brief          Compare signed values
+ *
+ * \return         1 if X is greater than z,
+ *                -1 if X is lesser  than z or
+ *                 0 if X is equal to z
+ */
+int che_mpi_cmp_int( mpi *X, int z );
+
+/**
+ * \brief          Unsigned addition: X = |A| + |B|
+ *
+ * \return         0 if successful,
+ *                 1 if memory allocation failed
+ */
+int che_mpi_add_abs( mpi *X, mpi *A, mpi *B );
+
+/**
+ * \brief          Unsigned substraction: X = |A| - |B|
+ *
+ * \return         0 if successful,
+ *                 XYSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A
+ */
+int che_mpi_sub_abs( mpi *X, mpi *A, mpi *B );
+
+/**
+ * \brief          Signed addition: X = A + B
+ *
+ * \return         0 if successful,
+ *                 1 if memory allocation failed
+ */
+int che_mpi_add_mpi( mpi *X, mpi *A, mpi *B );
+
+/**
+ * \brief          Signed substraction: X = A - B
+ *
+ * \return         0 if successful,
+ *                 1 if memory allocation failed
+ */
+int che_mpi_sub_mpi( mpi *X, mpi *A, mpi *B );
+
+/**
+ * \brief          Signed addition: X = A + b
+ *
+ * \return         0 if successful,
+ *                 1 if memory allocation failed
+ */
+int che_mpi_add_int( mpi *X, mpi *A, int b );
+
+/**
+ * \brief          Signed substraction: X = A - b
+ *
+ * \return         0 if successful,
+ *                 1 if memory allocation failed
+ */
+int che_mpi_sub_int( mpi *X, mpi *A, int b );
+
+/**
+ * \brief          Baseline multiplication: X = A * B
+ *
+ * \return         0 if successful,
+ *                 1 if memory allocation failed
+ */
+int che_mpi_mul_mpi( mpi *X, mpi *A, mpi *B );
+
+/**
+ * \brief          Baseline multiplication: X = A * b
+ *
+ * \return         0 if successful,
+ *                 1 if memory allocation failed
+ */
+int che_mpi_mul_int( mpi *X, mpi *A, t_int b );
+
+/**
+ * \brief          Division by mpi: A = Q * B + R
+ *
+ * \return         0 if successful,
+ *                 1 if memory allocation failed,
+ *                 XYSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
+ *
+ * \note           Either Q or R can be NULL.
+ */
+int che_mpi_div_mpi( mpi *Q, mpi *R, mpi *A, mpi *B );
+
+/**
+ * \brief          Division by int: A = Q * b + R
+ *
+ * \return         0 if successful,
+ *                 1 if memory allocation failed,
+ *                 XYSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
+ *
+ * \note           Either Q or R can be NULL.
+ */
+int che_mpi_div_int( mpi *Q, mpi *R, mpi *A, int b );
+
+/**
+ * \brief          Modulo: R = A mod B
+ *
+ * \return         0 if successful,
+ *                 1 if memory allocation failed,
+ *                 XYSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
+ */
+int che_mpi_mod_mpi( mpi *R, mpi *A, mpi *B );
+
+/**
+ * \brief          Modulo: r = A mod b
+ *
+ * \return         0 if successful,
+ *                 1 if memory allocation failed,
+ *                 XYSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
+ */
+int che_mpi_mod_int( t_int *r, mpi *A, int b );
+
+/**
+ * \brief          Sliding-window exponentiation: X = A^E mod N
+ *
+ * \return         0 if successful,
+ *                 1 if memory allocation failed,
+ *                 XYSSL_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 che_mpi_exp_mod( mpi *X, mpi *A, mpi *E, mpi *N, mpi *_RR );
+
+/**
+ * \brief          Greatest common divisor: G = gcd(A, B)
+ *
+ * \return         0 if successful,
+ *                 1 if memory allocation failed
+ */
+int che_mpi_gcd( mpi *G, mpi *A, mpi *B );
+
+/**
+ * \brief          Modular inverse: X = A^-1 mod N
+ *
+ * \return         0 if successful,
+ *                 1 if memory allocation failed,
+ *                 XYSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
+ *                 XYSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
+ */
+int che_mpi_inv_mod( mpi *X, mpi *A, mpi *N );
+
+/**
+ * \brief          Miller-Rabin primality test
+ *
+ * \return         0 if successful (probably prime),
+ *                 1 if memory allocation failed,
+ *                 XYSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime
+ */
+int che_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,
+ *                 XYSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
+ */
+int che_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 che_mpi_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* bignum.h */
diff --git a/mcu/driver/che/include/bn_mul.h b/mcu/driver/che/include/bn_mul.h
new file mode 100644
index 0000000..ad1ac92
--- /dev/null
+++ b/mcu/driver/che/include/bn_mul.h
@@ -0,0 +1,612 @@
+/**
+ * \file bn_mul.h
+ */
+/*
+ *      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 XYSSL_BN_MUL_H
+#define XYSSL_BN_MUL_H
+
+#if defined(XYSSL_HAVE_ASM)
+
+#if defined(__GNUC__)
+#if defined(__i386__)
+
+#define MULADDC_INIT                            \
+    asm( "movl   %%ebx, %0      " : "=m" (t));  \
+    asm( "movl   %0, %%esi      " :: "m" (s));  \
+    asm( "movl   %0, %%edi      " :: "m" (d));  \
+    asm( "movl   %0, %%ecx      " :: "m" (c));  \
+    asm( "movl   %0, %%ebx      " :: "m" (b));
+
+#define MULADDC_CORE                            \
+    asm( "lodsl                 " );            \
+    asm( "mull   %ebx           " );            \
+    asm( "addl   %ecx,   %eax   " );            \
+    asm( "adcl   $0,     %edx   " );            \
+    asm( "addl   (%edi), %eax   " );            \
+    asm( "adcl   $0,     %edx   " );            \
+    asm( "movl   %edx,   %ecx   " );            \
+    asm( "stosl                 " );
+
+#define MULADDC_STOP                            \
+    asm( "movl   %0, %%ebx      " :: "m" (t));  \
+    asm( "movl   %%ecx, %0      " : "=m" (c));  \
+    asm( "movl   %%edi, %0      " : "=m" (d));  \
+    asm( "movl   %%esi, %0      " : "=m" (s) :: \
+    "eax", "ecx", "edx", "esi", "edi" );
+
+#if defined(XYSSL_HAVE_SSE2)
+
+#define MULADDC_HUIT                            \
+    asm( "movd     %ecx,     %mm1     " );      \
+    asm( "movd     %ebx,     %mm0     " );      \
+    asm( "movd     (%edi),   %mm3     " );      \
+    asm( "paddq    %mm3,     %mm1     " );      \
+    asm( "movd     (%esi),   %mm2     " );      \
+    asm( "pmuludq  %mm0,     %mm2     " );      \
+    asm( "movd     4(%esi),  %mm4     " );      \
+    asm( "pmuludq  %mm0,     %mm4     " );      \
+    asm( "movd     8(%esi),  %mm6     " );      \
+    asm( "pmuludq  %mm0,     %mm6     " );      \
+    asm( "movd     12(%esi), %mm7     " );      \
+    asm( "pmuludq  %mm0,     %mm7     " );      \
+    asm( "paddq    %mm2,     %mm1     " );      \
+    asm( "movd     4(%edi),  %mm3     " );      \
+    asm( "paddq    %mm4,     %mm3     " );      \
+    asm( "movd     8(%edi),  %mm5     " );      \
+    asm( "paddq    %mm6,     %mm5     " );      \
+    asm( "movd     12(%edi), %mm4     " );      \
+    asm( "paddq    %mm4,     %mm7     " );      \
+    asm( "movd     %mm1,     (%edi)   " );      \
+    asm( "movd     16(%esi), %mm2     " );      \
+    asm( "pmuludq  %mm0,     %mm2     " );      \
+    asm( "psrlq    $32,      %mm1     " );      \
+    asm( "movd     20(%esi), %mm4     " );      \
+    asm( "pmuludq  %mm0,     %mm4     " );      \
+    asm( "paddq    %mm3,     %mm1     " );      \
+    asm( "movd     24(%esi), %mm6     " );      \
+    asm( "pmuludq  %mm0,     %mm6     " );      \
+    asm( "movd     %mm1,     4(%edi)  " );      \
+    asm( "psrlq    $32,      %mm1     " );      \
+    asm( "movd     28(%esi), %mm3     " );      \
+    asm( "pmuludq  %mm0,     %mm3     " );      \
+    asm( "paddq    %mm5,     %mm1     " );      \
+    asm( "movd     16(%edi), %mm5     " );      \
+    asm( "paddq    %mm5,     %mm2     " );      \
+    asm( "movd     %mm1,     8(%edi)  " );      \
+    asm( "psrlq    $32,      %mm1     " );      \
+    asm( "paddq    %mm7,     %mm1     " );      \
+    asm( "movd     20(%edi), %mm5     " );      \
+    asm( "paddq    %mm5,     %mm4     " );      \
+    asm( "movd     %mm1,     12(%edi) " );      \
+    asm( "psrlq    $32,      %mm1     " );      \
+    asm( "paddq    %mm2,     %mm1     " );      \
+    asm( "movd     24(%edi), %mm5     " );      \
+    asm( "paddq    %mm5,     %mm6     " );      \
+    asm( "movd     %mm1,     16(%edi) " );      \
+    asm( "psrlq    $32,      %mm1     " );      \
+    asm( "paddq    %mm4,     %mm1     " );      \
+    asm( "movd     28(%edi), %mm5     " );      \
+    asm( "paddq    %mm5,     %mm3     " );      \
+    asm( "movd     %mm1,     20(%edi) " );      \
+    asm( "psrlq    $32,      %mm1     " );      \
+    asm( "paddq    %mm6,     %mm1     " );      \
+    asm( "movd     %mm1,     24(%edi) " );      \
+    asm( "psrlq    $32,      %mm1     " );      \
+    asm( "paddq    %mm3,     %mm1     " );      \
+    asm( "movd     %mm1,     28(%edi) " );      \
+    asm( "addl     $32,      %edi     " );      \
+    asm( "addl     $32,      %esi     " );      \
+    asm( "psrlq    $32,      %mm1     " );      \
+    asm( "movd     %mm1,     %ecx     " );
+
+#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__)
+
+#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( "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 /* 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
+
+#define MULADDC_STOP                            \
+    __asm   mov     c, ecx                      \
+    __asm   mov     d, edi                      \
+    __asm   mov     s, esi                      \
+
+#if defined(XYSSL_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
+
+#endif /* SSE2 */
+#endif /* MSVC */
+
+#endif /* XYSSL_HAVE_ASM */
+
+#if !defined(MULADDC_CORE)
+#if defined(XYSSL_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/mcu/driver/che/include/che_hw.h b/mcu/driver/che/include/che_hw.h
new file mode 100644
index 0000000..0d4f852
--- /dev/null
+++ b/mcu/driver/che/include/che_hw.h
@@ -0,0 +1,432 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ *
+ * Filename:
+ * ---------
+ * che_hw.h
+ *
+ * Project:
+ * --------
+ *   MAUI
+ *
+ * Description:
+ * ------------
+ *   Cipher/hash engine hw register definitions.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *==============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by ClearCase. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * $Log$
+ *
+ * 11 26 2010 carlos.yeh
+ * removed!
+ * Initial checkin for HAL
+ *
+ * removed!
+ * removed!
+ * 
+ *
+ * removed!
+ * removed!
+ * 
+ *
+ * removed!
+ * removed!
+ * 
+ *
+ * removed!
+ * removed!
+ * 
+ *
+ * removed!
+ * removed!
+ * 
+ *
+ * removed!
+ * removed!
+ * 
+ *
+ * removed!
+ * removed!
+ * 
+ *
+ * removed!
+ * removed!
+ * 
+ *
+ * removed!
+ * removed!
+ * 
+ *
+ *    Rev 1.1   Jun 06 2005 19:29:20   mtk00288
+ * Revise HW register.
+ * Resolution for 11205: [Video/Drv][Add feature]Add MT6228 option
+ *
+ *    Rev 1.0   Jun 06 2005 12:57:20   BM
+ * Initial revision.
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by ClearCase. DO NOT MODIFY!!
+ *==============================================================================
+ *******************************************************************************/
+#ifndef CHE_HW_H
+#define CHE_HW_H
+
+#include "drvpdn.h"
+#include "reg_base.h"
+#include "che_api.h"
+
+#ifndef __HW_CHE__
+#define che_slowdown()
+#define che_recover()
+#else
+void che_slowdown(void);
+void che_recover(void);
+#endif
+
+
+#if defined(__CLKG_DEFINE__)
+#define  CHE_PDN_SET     (CG_SET0)
+#define  CHE_PDN_CLR     (CG_CLR0)
+#else
+#define  CHE_PDN_SET     (0x80000310)
+#define  CHE_PDN_CLR     (0x80000320)
+#endif
+
+#define  CHE_PDN_BIT     0x10
+
+#define  CHE_START       (CHE_base+0x0)
+#define  CHE_CON         (CHE_base+0x4)
+#define  CHE_IN0         (CHE_base+0x8)
+#define  CHE_IN1         (CHE_base+0xc)
+#define  CHE_IN2         (CHE_base+0x10)
+#define  CHE_IN3         (CHE_base+0x14)
+#define  CHE_SDRAT       (CHE_base+0x18)
+#define  CHE_PCNT        (CHE_base+0x1c)     /*RO*/
+#define  CHE_STAT        (CHE_base+0x20)     /*RO*/
+#define  CHE_CDES        (CHE_base+0x24)     /*RO*/
+#define  CHE_INTSTA      (CHE_base+0x28)     /*RC*/
+#define  CHE_INTEN       (CHE_base+0x2c)     /*RW*/
+#define  CHE_BCON        (CHE_base+0xc0)
+#define  CHE_BSRC        (CHE_base+0xc4)
+#define  CHE_BSEED       (CHE_base+0xc8)
+#define  CHE_BENC        (CHE_base+0xcc)
+#define  CHE_BDEC        (CHE_base+0xd0)
+
+/*CHE_START*/
+#define  CHE_START_DONE       0x0000
+#define  CHE_START_STUD       0x0001
+#define  CHE_START_LAST       0x0002
+#define  CHE_START_WSTAT      0x0004
+#define  CHE_START_RSTAT      0x0008
+#define  CHE_START_CLEAR      0x0010
+#define  CHE_START_UPDES      0x0020
+#define  CHE_START_WKEY       0x0040
+#define  CHE_START_RKEY       0x0080
+#define  CHE_START_UPIV01     0x0100
+#define  CHE_START_UPIV23     0x0200
+#define  CHE_START_UPK01      0x0400
+#define  CHE_START_UPK23      0x0800
+#define  CHE_START_UPK45      0x1000
+#define  CHE_START_UPK67      0x2000
+
+/*CHE_CON*/
+#define  CHE_CON_ATYPE_MASK         0x0007
+#define  CHE_CON_ATYPE_MD5          0x0
+#define  CHE_CON_ATYPE_SHA1         0x1
+#define  CHE_CON_ATYPE_DES          0x2
+#define  CHE_CON_ATYPE_3DES         0x3
+#define  CHE_CON_ATYPE_AES_128      0x4
+#define  CHE_CON_ATYPE_AES_192      0x5
+#define  CHE_CON_ATYPE_AES_256      0x6
+#define  CHE_CON_DECIPHER           0x0000
+#define  CHE_CON_CIPHER             0x0008
+#define  CHE_CON_SMODE_ECB          0x0000
+#define  CHE_CON_SMODE_CBC          0x0010
+#define  CHE_CON_DKEY1_64BIT        0x0000
+#define  CHE_CON_DKEY1_56BIT        0x0020
+#define  CHE_CON_DKEY2_64BIT        0x0000
+#define  CHE_CON_DKEY2_56BIT        0x0040
+#define  CHE_CON_DKEY3_64BIT        0x0000
+#define  CHE_CON_DKEY3_56BIT        0x0080
+
+/*CHE_IN0*/
+#define  CHE_IN0_MASK         0xffffffff
+
+/*CHE_IN1*/
+#define  CHE_IN1_MASK         0xffffffff
+
+/*CHE_IN2*/
+#define  CHE_IN2_MASK         0xffffffff
+
+/*CHE_IN3*/
+#define  CHE_IN3_MASK         0xffffffff
+
+/*CHE_SDRAT*/
+#define  CHE_SDRAT_MASK       0x00ff      /*RW*/
+
+/*CHE_PCNT*/
+#define  CHE_PCNT_MASK        0x001f
+
+/*CHE_STAT*/
+#define  CHE_STAT_MASK        0x0007      /*RO*/
+#define  CHE_STAT_OK          0x0000      /*RO*/
+#define  CHE_STAT_CTRL_ERR    0x0001      /*RO*/
+#define  CHE_STAT_ZEROLEN     0x0002      /*RO*/
+#define  CHE_STAT_RESUME      0x0003      /*RO*/
+#define  CHE_STAT_BUSY        0x0004      /*RO*/
+
+/*CHE_CDES*/
+#define  CHE_CDES_MASK        0xffffffff
+
+/*CHE_INTSTA*/
+#define  CHE_INTSTA_OK        0x1
+#define  CHE_INTSTA_FAIL      0x2
+#define  CHE_INTSTA_RESUME    0x3   //??
+
+/*CHE_INTEN*/
+#define  CHE_INTEN_OK         0x1
+#define  CHE_INTEN_FAIL       0x2
+
+#define CHE_REGSET_START(_data)  \
+{\
+   DRV_WriteReg32(CHE_START, (_data));\
+   che_hw_setting[CHE_HW_SETTING_START] = (_data);\
+}
+
+#define CHE_REGSET_INTEN(_data)  \
+{\
+   DRV_WriteReg32(CHE_INTEN, (_data));\
+   che_hw_setting[CHE_HW_SETTING_INTEN] = (_data);\
+}
+
+#define CHE_REGSET_CON(_data)  \
+{\
+   DRV_WriteReg32(CHE_CON, (_data));\
+   che_hw_setting[CHE_HW_SETTING_CON] = (_data);\
+}
+
+#define CHE_REGSET_KEY0(_data)  \
+{\
+   DRV_WriteReg32(CHE_IN0, (_data));\
+   che_hw_setting[CHE_HW_SETTING_KEY0] = (_data);\
+}
+
+#define CHE_REGSET_KEY1(_data)  \
+{\
+   DRV_WriteReg32(CHE_IN1, (_data));\
+   che_hw_setting[CHE_HW_SETTING_KEY1] = (_data);\
+}
+
+#define CHE_REGSET_KEY2(_data)  \
+{\
+   DRV_WriteReg32(CHE_IN2, (_data));\
+   che_hw_setting[CHE_HW_SETTING_KEY2] = (_data);\
+}
+
+#define CHE_REGSET_KEY3(_data)  \
+{\
+   DRV_WriteReg32(CHE_IN3, (_data));\
+   che_hw_setting[CHE_HW_SETTING_KEY3] = (_data);\
+}
+
+#define CHE_REGSET_KEY4(_data)  \
+{\
+   DRV_WriteReg32(CHE_IN0, (_data));\
+   che_hw_setting[CHE_HW_SETTING_KEY4] = (_data);\
+}
+
+#define CHE_REGSET_KEY5(_data)  \
+{\
+   DRV_WriteReg32(CHE_IN1, (_data));\
+   che_hw_setting[CHE_HW_SETTING_KEY5] = (_data);\
+}
+
+#define CHE_REGSET_KEY6(_data)  \
+{\
+   DRV_WriteReg32(CHE_IN2, (_data));\
+   che_hw_setting[CHE_HW_SETTING_KEY6] = (_data);\
+}
+
+#define CHE_REGSET_KEY7(_data)  \
+{\
+   DRV_WriteReg32(CHE_IN3, (_data));\
+   che_hw_setting[CHE_HW_SETTING_KEY7] = (_data);\
+}
+
+#define CHE_REGSET_CKEY(_data)  \
+{\
+   DRV_WriteReg32(CHE_IN3, (_data));\
+   che_hw_setting[CHE_HW_SETTING_CKEY] = (_data);\
+}
+
+#define CHE_REGSET_IV0(_data)  \
+{\
+   DRV_WriteReg32(CHE_IN0, (_data));\
+   che_hw_setting[CHE_HW_SETTING_IV0] = (_data);\
+}
+
+#define CHE_REGSET_IV1(_data)  \
+{\
+   DRV_WriteReg32(CHE_IN1, (_data));\
+   che_hw_setting[CHE_HW_SETTING_IV1] = (_data);\
+}
+
+#define CHE_REGSET_IV2(_data)  \
+{\
+   DRV_WriteReg32(CHE_IN2, (_data));\
+   che_hw_setting[CHE_HW_SETTING_IV2] = (_data);\
+}
+
+#define CHE_REGSET_IV3(_data)  \
+{\
+   DRV_WriteReg32(CHE_IN3, (_data));\
+   che_hw_setting[CHE_HW_SETTING_IV3] = (_data);\
+}
+
+#define CHE_REGSET_SRC(_data)  \
+{\
+   DRV_WriteReg32(CHE_IN0, _data);\
+   che_hw_setting[CHE_HW_SETTING_SRC] = (_data);\
+}
+
+#define CHE_REGSET_DST(_data)  \
+{\
+   DRV_WriteReg32(CHE_IN1, _data);\
+   che_hw_setting[CHE_HW_SETTING_DST] = (_data);\
+}
+
+#define CHE_REGSET_LEN(_data)  \
+{\
+   DRV_WriteReg32(CHE_IN2, _data);\
+   che_hw_setting[CHE_HW_SETTING_LEN] = (_data);\
+}
+
+#define CHE_REGSET_SADDR(_data)  \
+{\
+   DRV_WriteReg32(CHE_IN3, _data);\
+   che_hw_setting[CHE_HW_SETTING_SADDR] = (_data);\
+}
+
+#define CHE_WAIT_STAT_OK()  \
+{\
+   kal_uint32 status;\
+   while(DRV_Reg32(CHE_STAT) != CHE_STAT_OK);\
+   status = DRV_Reg32(CHE_INTSTA);\
+}
+
+#define CHE_WAIT_STAT_RESUME()  \
+{\
+   kal_uint32 status;\
+   while(DRV_Reg32(CHE_STAT) != CHE_STAT_RESUME);\
+   status = DRV_Reg32(CHE_INTSTA);\
+}
+
+
+
+#define CHE_MAX_CHANNEL       32
+#define CHE_HW_STATUS_SIZE    120
+//#define CHE_INTR_ENABLE
+
+/*AES 10000, DES 20000*/
+#define ISR_ENABLE_DATA_LENGTH      15000
+
+typedef enum {
+   CHE_HW_SETTING_START = 0,
+   CHE_HW_SETTING_CON,  /*1*/
+   CHE_HW_SETTING_KEY0, /*2*/
+   CHE_HW_SETTING_KEY1, /*3*/
+   CHE_HW_SETTING_KEY2, /*4*/
+   CHE_HW_SETTING_KEY3, /*5*/
+   CHE_HW_SETTING_KEY4, /*6*/
+   CHE_HW_SETTING_KEY5, /*7*/
+   CHE_HW_SETTING_KEY6, /*8*/
+   CHE_HW_SETTING_KEY7, /*9*/
+   CHE_HW_SETTING_CKEY, /*10*/
+   CHE_HW_SETTING_IV0,  /*11*/
+   CHE_HW_SETTING_IV1,  /*12*/
+   CHE_HW_SETTING_IV2,  /*13*/
+   CHE_HW_SETTING_IV3,  /*14*/
+   CHE_HW_SETTING_SRC,  /*15*/
+   CHE_HW_SETTING_DST,  /*16*/
+   CHE_HW_SETTING_LEN,  /*17*/
+   CHE_HW_SETTING_SADDR,   /*18*/   //state addr
+   CHE_HW_SETTING_INTEN,   /*19*/
+   CHE_HW_SETTING_DUMMY1,  /*20*/
+   CHE_HW_SETTING_DUMMY2,  /*21*/
+   CHE_HW_SETTING_DUMMY3,  /*22*/
+   CHE_HW_SETTING_DUMMY4,  /*23*/
+   CHE_HW_SETTING_DUMMY5,  /*24*/
+   CHE_HW_SETTING_DUMMY6,  /*25*/
+   CHE_HW_SETTING_DUMMY7,  /*26*/
+   CHE_HW_SETTING_DUMMY8,  /*27*/
+   MAX_CHE_HW_SETTING      /*28*/
+} CHE_HW_SETTING;
+
+typedef struct {
+   kal_uint32           che_glb_handle;            /*CHE global handle*/
+   kal_uint8            che_lastest_finish_handle; /*Avoid race condition*/
+   kal_bool             che_machie_running;  /*Avoid race condition*/
+   kal_uint32           che_dbg_line;     /*Just for debug*/
+   kal_uint8            che_sm_handle;    /*CHE SM control*/
+   kal_hisrid           hisr;             /*CHE HISR*/
+   kal_eventgrpid       event;            /*CHE EVENT*/
+} CHE_CB_DATA_STRUCT;
+
+
+void convert_des_Key(kal_uint8 *key, kal_uint32 *ckey);
+void convert_3des_Key(kal_uint8 *key, kal_uint32 *ckey);
+void convert_aes_Key(kal_uint8 *key, kal_uint8 *ckey);
+void convert_aes_128_key(kal_uint8 *key, kal_uint8 *ckey);
+void convert_aes_192_key(kal_uint8 *key, kal_uint8 *ckey);
+void convert_aes_256_key(kal_uint8 *key, kal_uint8 *ckey);
+
+void des_set_iv(kal_uint8 *cheIV);
+void aes_set_iv(kal_uint8 *cheIV);
+
+
+kal_bool che_hw_aes(STCHE* che_context, kal_uint8 *srcData, kal_uint8 *encryptedData, kal_uint32 data_length, CHE_OPERATION_MODE mode, CHE_ACTION act, kal_bool last_block);
+kal_bool che_hw_des(STCHE* che_context,kal_uint8 *srcData, kal_uint8 *encryptedData, kal_uint32 data_length, CHE_TYPE type, CHE_OPERATION_MODE mode, CHE_ACTION act, kal_bool last_block);
+kal_uint32 che_hw_hash(STCHE* che_context, CHE_TYPE type, kal_uint8 *srcData, kal_uint8 *output_data,  kal_uint32 data_length, kal_bool last_block);
+
+
+#endif
diff --git a/mcu/driver/che/include/des.h b/mcu/driver/che/include/des.h
new file mode 100644
index 0000000..9b56666
--- /dev/null
+++ b/mcu/driver/che/include/des.h
@@ -0,0 +1,221 @@
+/* Copyright (C) 1996 Eric Young (eay@mincom.oz.au)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@mincom.oz.au).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@mincom.oz.au).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@mincom.oz.au)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+ 
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *    des.h
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   des software function.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+#ifndef __DES_H__
+#define __DES_H__
+
+#include "kal_general_types.h"
+
+typedef kal_uint8 des_cblock[8];
+typedef struct des_ks_struct{
+   union{
+      des_cblock _;
+      kal_uint32 pad[2];
+   } ks;
+#undef _
+#define _	ks._
+} des_key_schedule[16];
+
+
+#define DES_KEY_SZ 	(sizeof(des_cblock))
+#define DES_SCHEDULE_SZ (sizeof(des_key_schedule))
+
+#define DES_ENCRYPT	1
+#define DES_DECRYPT	0
+
+#define DES_CBC_MODE	0
+#define DES_PCBC_MODE	1
+
+#define C_Block des_cblock
+#define Key_schedule des_key_schedule
+
+
+#define ITERATIONS 16
+#define HALF_ITERATIONS 8
+
+#define c2l(c,l)(l =((kal_uint32)(*((c)++)))    , \
+		 l|=((kal_uint32)(*((c)++)))<< 8L, \
+		 l|=((kal_uint32)(*((c)++)))<<16L, \
+		 l|=((kal_uint32)(*((c)++)))<<24L)
+
+
+#define l2c(l,c)(*((c)++)=(kal_uint8)(((l)     )&0xff), \
+		 *((c)++)=(kal_uint8)(((l)>> 8L)&0xff), \
+		 *((c)++)=(kal_uint8)(((l)>>16L)&0xff), \
+		 *((c)++)=(kal_uint8)(((l)>>24L)&0xff))
+
+
+
+#define	ROTATE(a,n)	(((a)>>(n))+((a)<<(32-(n))))
+
+#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
+	u=R^s[S  ]; \
+	t=R^s[S+1]
+
+#define D_ENCRYPT(LL,R,S) {\
+	LOAD_DATA_tmp(R,S,u,t,E0,E1); \
+	t=ROTATE(t,4); \
+	LL^=\
+		des_SPtrans[0][(u>> 2L)&0x3f]^ \
+		des_SPtrans[2][(u>>10L)&0x3f]^ \
+		des_SPtrans[4][(u>>18L)&0x3f]^ \
+		des_SPtrans[6][(u>>26L)&0x3f]^ \
+		des_SPtrans[1][(t>> 2L)&0x3f]^ \
+		des_SPtrans[3][(t>>10L)&0x3f]^ \
+		des_SPtrans[5][(t>>18L)&0x3f]^ \
+		des_SPtrans[7][(t>>26L)&0x3f]; }
+		
+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+	(b)^=(t),\
+	(a)^=((t)<<(n)))
+
+#define IP(l,r) \
+	{ \
+	register kal_uint32 tt; \
+	PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
+	PERM_OP(l,r,tt,16,0x0000ffffL); \
+	PERM_OP(r,l,tt, 2,0x33333333L); \
+	PERM_OP(l,r,tt, 8,0x00ff00ffL); \
+	PERM_OP(r,l,tt, 1,0x55555555L); \
+	}
+
+#define FP(l,r) \
+	{ \
+	register kal_uint32 tt; \
+	PERM_OP(l,r,tt, 1,0x55555555L); \
+	PERM_OP(r,l,tt, 8,0x00ff00ffL); \
+	PERM_OP(l,r,tt, 2,0x33333333L); \
+	PERM_OP(r,l,tt,16,0x0000ffffL); \
+	PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
+	}
+
+
+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
+	(a)=(a)^(t)^(t>>(16-(n))))
+
+
+
+kal_int32 CHE_des_key_sched(des_cblock *key, des_key_schedule *schedule);
+void CHE_des_ecb_encrypt(des_cblock *input, des_cblock *output, des_key_schedule *ks, kal_int32 encrypt);
+
+#endif  //__DES_H__
diff --git a/mcu/driver/che/include/dhm.h b/mcu/driver/che/include/dhm.h
new file mode 100644
index 0000000..85f1bef
--- /dev/null
+++ b/mcu/driver/che/include/dhm.h
@@ -0,0 +1,127 @@
+/**
+ * \file dhm.h
+ */
+#ifndef XYSSL_DHM_H
+#define XYSSL_DHM_H
+
+#include "bignum.h"
+
+#define XYSSL_ERR_DHM_BAD_INPUT_DATA                    -0x0480
+#define XYSSL_ERR_DHM_READ_PARAMS_FAILED                -0x0490
+#define XYSSL_ERR_DHM_MAKE_PARAMS_FAILED                -0x04A0
+#define XYSSL_ERR_DHM_READ_PUBLIC_FAILED                -0x04B0
+#define XYSSL_ERR_DHM_MAKE_PUBLIC_FAILED                -0x04C0
+#define XYSSL_ERR_DHM_CALC_SECRET_FAILED                -0x04D0
+
+typedef struct
+{
+    int len;    /*!<  size(P) in chars  */
+    mpi P;      /*!<  prime modulus     */
+    mpi G;      /*!<  generator         */
+    mpi X;      /*!<  secret value      */
+    mpi GX;     /*!<  self = G^X mod P  */
+    mpi GY;     /*!<  peer = G^Y mod P  */
+    mpi K;      /*!<  key = GY^X mod P  */
+    mpi RP;     /*!<  cached R^2 mod P  */
+}dhm_context;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          Parse the ServerKeyExchange parameters
+ *
+ * \param ctx      DHM context
+ * \param p        &(start of input buffer)
+ * \param end      end of buffer
+ *
+ * \return         0 if successful, or an XYSSL_ERR_DHM_XXX error code
+ */
+int dhm_read_params( dhm_context *ctx,
+                     unsigned char **p,
+                     unsigned char *end );
+
+/**
+ * \brief          Setup and write the ServerKeyExchange parameters
+ *
+ * \param ctx      DHM context
+ * \param x_size   private value size in bits
+ * \param output   destination buffer
+ * \param olen     number of chars written
+ * \param f_rng    RNG function
+ * \param p_rng    RNG parameter
+ *
+ * \note           This function assumes that ctx->P and ctx->G
+ *                 have already been properly set (for example
+ *                 using che_mpi_read_string or che_mpi_read_binary).
+ *
+ * \return         0 if successful, or an XYSSL_ERR_DHM_XXX error code
+ */
+int dhm_make_params( dhm_context *ctx, int s_size,
+                     unsigned char *output, int *olen,
+                     int (*f_rng)(void *), void *p_rng );
+
+int dhm_make_params_internal( dhm_context *ctx, int x_size,
+                              int (*f_rng)(void *), void *p_rng );
+
+/**
+ * \brief          Import the peer's public value G^Y
+ *
+ * \param ctx      DHM context
+ * \param input    input buffer
+ * \param ilen     size of buffer
+ *
+ * \return         0 if successful, or an XYSSL_ERR_DHM_XXX error code
+ */
+int dhm_read_public( dhm_context *ctx,
+                     unsigned char *input, int ilen );
+
+/**
+ * \brief          Create own private value X and export G^X
+ *
+ * \param ctx      DHM context
+ * \param x_size   private value size in bits
+ * \param output   destination buffer
+ * \param olen     must be equal to ctx->P.len
+ * \param f_rng    RNG function
+ * \param p_rng    RNG parameter
+ *
+ * \return         0 if successful, or an XYSSL_ERR_DHM_XXX error code
+ */
+int dhm_make_public( dhm_context *ctx, int s_size,
+                     unsigned char *output, int olen,
+                     int (*f_rng)(void *), void *p_rng );
+int dhm_make_public_internal( dhm_context *ctx, int x_size,
+                              int (*f_rng)(void *), void *p_rng );
+
+/**
+ * \brief          Derive and export the shared secret (G^Y)^X mod P
+ *
+ * \param ctx      DHM context
+ * \param output   destination buffer
+ * \param olen     number of chars written
+ *
+ * \return         0 if successful, or an XYSSL_ERR_DHM_XXX error code
+ */
+int dhm_calc_secret( dhm_context *ctx,
+                     unsigned char *output, int *olen );
+int dhm_calc_secret_internal( dhm_context *ctx);
+
+/*
+ * \brief          Free the components of a DHM key
+ */
+void dhm_free( dhm_context *ctx );
+
+/**
+ * \brief          Checkup routine
+ *
+ * \return         0 if successful, or 1 if the test failed
+ */
+int dhm_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/mcu/driver/che/include/md32_common.h b/mcu/driver/che/include/md32_common.h
new file mode 100644
index 0000000..7e00e87
--- /dev/null
+++ b/mcu/driver/che/include/md32_common.h
@@ -0,0 +1,337 @@
+/* crypto/md32_common.h */
+/* ====================================================================
+ * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+/*
+ * This is a generic 32 bit "collector" for message digest algorithms.
+ * Whenever needed it collects input character stream into chunks of
+ * 32 bit values and invokes a block function that performs actual hash
+ * calculations.
+ *
+ * Porting guide.
+ *
+ * Obligatory macros:
+ *
+ * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
+ *	this macro defines byte order of input stream.
+ * HASH_CBLOCK
+ *	size of a unit chunk HASH_BLOCK operates on.
+ * HASH_LONG
+ *	has to be at lest 32 bit wide, if it's wider, then
+ *	HASH_LONG_LOG2 *has to* be defined along
+ * HASH_CTX
+ *	context structure that at least contains following
+ *	members:
+ *		typedef struct {
+ *			...
+ *			HASH_LONG	Nl,Nh;
+ *			either {
+ *			HASH_LONG	data[HASH_LBLOCK];
+ *			unsigned char	data[HASH_CBLOCK];
+ *			};
+ *			unsigned int	num;
+ *			...
+ *			} HASH_CTX;
+ *	data[] vector is expected to be zeroed upon first call to
+ *	HASH_UPDATE.
+ * HASH_UPDATE
+ *	name of "Update" function, implemented here.
+ * HASH_TRANSFORM
+ *	name of "Transform" function, implemented here.
+ * HASH_FINAL
+ *	name of "Final" function, implemented here.
+ * HASH_BLOCK_DATA_ORDER
+ *	name of "block" function capable of treating *unaligned* input
+ *	message in original (data) byte order, implemented externally.
+ * HASH_MAKE_STRING
+ *	macro convering context variables to an ASCII hash string.
+ *
+ * MD5 example:
+ *
+ *	#define DATA_ORDER_IS_LITTLE_ENDIAN
+ *
+ *	#define HASH_LONG		MD5_LONG
+ *	#define HASH_LONG_LOG2		MD5_LONG_LOG2
+ *	#define HASH_CTX		MD5_CTX
+ *	#define HASH_CBLOCK		MD5_CBLOCK
+ *	#define HASH_UPDATE		MD5_Update
+ *	#define HASH_TRANSFORM		MD5_Transform
+ *	#define HASH_FINAL		MD5_Final
+ *	#define HASH_BLOCK_DATA_ORDER	md5_block_data_order
+ *
+ *					<appro@fy.chalmers.se>
+ */
+ /*****************************************************************************
+   *
+   * Filename:
+   * ---------
+   *    md32_common.h
+   *
+   * Project:
+   * --------
+   *   Maui_Software
+   *
+   * Description:
+   * ------------
+   *   SHA1 Engine
+   *
+   * Author:
+   * -------
+   *  Leona Chou (mtk01890)
+   *
+   *============================================================================
+   *             HISTORY
+   * Below this line, this part is controlled by ClearCase. DO NOT MODIFY!!
+   *------------------------------------------------------------------------------
+   * $Log$
+   *
+   * 10 06 2015 raymondwt.chen
+   * [MOLY00144208] [Jade] Fix che/sys_svc_sec/sys_svc build warnings
+   * .Fix build warnings
+ *
+ * 03 16 2011 leona.chou
+ * removed!
+ * .
+   *
+   *------------------------------------------------------------------------------
+   * Upper this line, this part is controlled by ClearCase. DO NOT MODIFY!!
+   *============================================================================
+   ****************************************************************************/
+#ifndef MD32_COMMON_H
+#define MD32_COMMON_H
+
+#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+#error "DATA_ORDER must be defined!"
+#endif
+       
+#ifndef HASH_CBLOCK
+#error "HASH_CBLOCK must be defined!"
+#endif
+#ifndef HASH_LONG
+#error "HASH_LONG must be defined!"
+#endif
+#ifndef HASH_CTX
+#error "HASH_CTX must be defined!"
+#endif
+       
+#ifndef HASH_UPDATE
+#error "HASH_UPDATE must be defined!"
+#endif
+#ifndef HASH_TRANSFORM
+#error "HASH_TRANSFORM must be defined!"
+#endif
+#ifndef HASH_FINAL
+#error "HASH_FINAL must be defined!"
+#endif
+       
+#ifndef HASH_BLOCK_DATA_ORDER
+#error "HASH_BLOCK_DATA_ORDER must be defined!"
+#endif
+
+#undef ROTATE
+#define ROTATE(a,n)     (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
+
+#if defined(DATA_ORDER_IS_BIG_ENDIAN)
+#define HOST_c2l(c,l)	(l =(((unsigned long)(*((c)++)))<<24),		\
+			 l|=(((unsigned long)(*((c)++)))<<16),		\
+			 l|=(((unsigned long)(*((c)++)))<< 8),		\
+			 l|=(((unsigned long)(*((c)++)))    ))
+			 
+#define HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)>>24)&0xff),	\
+			 *((c)++)=(unsigned char)(((l)>>16)&0xff),	\
+			 *((c)++)=(unsigned char)(((l)>> 8)&0xff),	\
+			 *((c)++)=(unsigned char)(((l)    )&0xff))
+
+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+#define HOST_c2l(c,l)	(l =(((unsigned long)(*((c)++)))    ),		\
+			 l|=(((unsigned long)(*((c)++)))<< 8),		\
+			 l|=(((unsigned long)(*((c)++)))<<16),		\
+			 l|=(((unsigned long)(*((c)++)))<<24))
+
+#define HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)    )&0xff),	\
+			 *((c)++)=(unsigned char)(((l)>> 8)&0xff),	\
+			 *((c)++)=(unsigned char)(((l)>>16)&0xff),	\
+			 *((c)++)=(unsigned char)(((l)>>24)&0xff))
+
+#endif
+
+/*
+ * Time for some action:-)
+ */
+
+int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len)
+{
+    const unsigned char *data=data_;
+    unsigned char *p;
+    HASH_LONG l;
+    size_t n;
+
+    if (len==0) return 1;
+
+    l=(c->Nl+(((HASH_LONG)len)<<3))&0xffffffffUL;
+    /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
+    * Wei Dai <weidai@eskimo.com> for pointing it out. */
+    if (l < c->Nl) /* overflow */
+        c->Nh++;
+    c->Nh+=(HASH_LONG)(len>>29);	/* might cause compiler warning on 16-bit */
+    c->Nl=l;
+    
+    n = c->num;
+    if (n != 0)
+    {
+        p=(unsigned char *)c->data;
+        
+        if (len >= HASH_CBLOCK || len+n >= HASH_CBLOCK)
+        {
+            memcpy (p+n,data,HASH_CBLOCK-n);
+            HASH_BLOCK_DATA_ORDER (c,p,1);
+            n      = HASH_CBLOCK-n;
+            data  += n;
+            len   -= n;
+            c->num = 0;
+            memset (p,0,HASH_CBLOCK);	/* keep it zeroed */
+        }
+        else
+        {
+            memcpy (p+n,data,len);
+            c->num += (unsigned int)len;
+            return 1;
+        }
+    }
+
+    n = len/HASH_CBLOCK;
+    if (n > 0)
+    {
+        HASH_BLOCK_DATA_ORDER (c,data,n);
+        n    *= HASH_CBLOCK;
+        data += n;
+        len  -= n;
+    }
+
+    if (len != 0)
+    {
+        p = (unsigned char *)c->data;
+        c->num = (unsigned int)len;
+        memcpy (p,data,len);
+    }
+    return 1;
+}
+
+
+void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data)
+{
+    HASH_BLOCK_DATA_ORDER (c,data,1);
+}
+
+
+int HASH_FINAL (unsigned char *md, HASH_CTX *c)
+{
+    unsigned char *p = (unsigned char *)c->data;
+    size_t n = c->num;
+
+    p[n] = 0x80; /* there is always room for one */
+    n++;
+
+    if (n > (HASH_CBLOCK-8))
+    {
+        memset (p+n,0,HASH_CBLOCK-n);
+        n=0;
+        HASH_BLOCK_DATA_ORDER (c,p,1);
+    }
+    memset (p+n,0,HASH_CBLOCK-8-n);
+
+    p += HASH_CBLOCK-8;
+#if   defined(DATA_ORDER_IS_BIG_ENDIAN)
+    (void)HOST_l2c(c->Nh,p);
+    (void)HOST_l2c(c->Nl,p);
+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+    (void)HOST_l2c(c->Nl,p);
+    (void)HOST_l2c(c->Nh,p);
+#endif
+    p -= HASH_CBLOCK;
+    HASH_BLOCK_DATA_ORDER (c,p,1);
+    c->num=0;
+    memset (p,0,HASH_CBLOCK);
+
+#ifndef HASH_MAKE_STRING
+#error "HASH_MAKE_STRING must be defined!"
+#else
+    HASH_MAKE_STRING(c,md);
+#endif
+
+    return 1;
+}
+
+#ifndef MD32_REG_T
+#define MD32_REG_T long
+/*
+ * This comment was originaly written for MD5, which is why it
+ * discusses A-D. But it basically applies to all 32-bit digests,
+ * which is why it was moved to common header file.
+ *
+ * In case you wonder why A-D are declared as long and not
+ * as MD5_LONG. Doing so results in slight performance
+ * boost on LP64 architectures. The catch is we don't
+ * really care if 32 MSBs of a 64-bit register get polluted
+ * with eventual overflows as we *save* only 32 LSBs in
+ * *either* case. Now declaring 'em long excuses the compiler
+ * from keeping 32 MSBs zeroed resulting in 13% performance
+ * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
+ * Well, to be honest it should say that this *prevents* 
+ * performance degradation.
+ *				<appro@fy.chalmers.se>
+ * Apparently there're LP64 compilers that generate better
+ * code if A-D are declared int. Most notably GCC-x86_64
+ * generates better code.
+ *				<appro@fy.chalmers.se>
+ */
+#endif
+
+#endif /* MD32_COMMON_H */
diff --git a/mcu/driver/che/include/md5.h b/mcu/driver/che/include/md5.h
new file mode 100644
index 0000000..a8a6c1c
--- /dev/null
+++ b/mcu/driver/che/include/md5.h
@@ -0,0 +1,137 @@
+/*
+  Copyright (C) 1999, 2002 Aladdin Enterprises.  All rights reserved.
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  L. Peter Deutsch
+  ghost@aladdin.com
+
+ */
+/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
+/*
+  Independent implementation of MD5 (RFC 1321).
+
+  This code implements the MD5 Algorithm defined in RFC 1321, whose
+  text is available at
+	http://www.ietf.org/rfc/rfc1321.txt
+  The code is derived from the text of the RFC, including the test suite
+  (section A.5) but excluding the rest of Appendix A.  It does not include
+  any code or documentation that is identified in the RFC as being
+  copyrighted.
+
+  The original and principal author of md5.h is L. Peter Deutsch
+  <ghost@aladdin.com>.  Other authors are noted in the change history
+  that follows (in reverse chronological order):
+
+  2002-04-13 lpd Removed support for non-ANSI compilers; removed
+	references to Ghostscript; clarified derivation from RFC 1321;
+	now handles byte order either statically or dynamically.
+  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
+	added conditionalization for C++ compilation from Martin
+	Purschke <purschke@bnl.gov>.
+  1999-05-03 lpd Original version.
+ */
+
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *    md5.c
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   MD5 Engine
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by ClearCase. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * $Log$
+ *
+ * removed!
+ * removed!
+ * 
+ *
+ * removed!
+ * removed!
+ * code review. remove redundant comment.
+ *
+ * removed!
+ * removed!
+ * 
+ *
+ * removed!
+ * removed!
+ * 
+ *
+ * removed!
+ * removed!
+ * 
+ *
+ * removed!
+ * removed!
+ * 
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by ClearCase. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+#ifndef __MD5_H__
+#define __MD5_H__
+
+
+
+typedef unsigned char md5_byte_t; /* 8-bit byte */
+typedef unsigned int md5_word_t; /* 32-bit word */
+
+/* Define the state of the MD5 Algorithm. */
+typedef struct md5_state_s {
+    md5_word_t count[2];	/* message length in bits, lsw first */
+    md5_word_t abcd[4];		/* digest buffer */
+    md5_byte_t buf[64];		/* accumulate block */
+} md5_context;
+
+#ifdef __cplusplus
+extern "C" 
+{
+#endif
+
+/* Initialize the algorithm. */
+void CHE_md5_init(md5_context *pms);
+
+/* Append a string to the message. */
+void CHE_md5_append(md5_context *pms, const md5_byte_t *data, int nbytes);
+
+/* Finish the message and return the digest. */
+void CHE_md5_finish(md5_context *pms, md5_byte_t digest[16]);
+
+#ifdef __cplusplus
+}  /* end extern "C" */
+#endif
+
+#endif /* md5_INCLUDED */
diff --git a/mcu/driver/che/include/rc4.h b/mcu/driver/che/include/rc4.h
new file mode 100644
index 0000000..f4942cd
--- /dev/null
+++ b/mcu/driver/che/include/rc4.h
@@ -0,0 +1,140 @@
+/*
+ * RC4 stream cipher
+ * Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * License
+ * -------
+ * 
+ * GPL v2:
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ * 
+ * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * (this copy of the license is in COPYING file)
+ * 
+ * 
+ * Alternatively, this software may be distributed, used, and modified
+ * under the terms of BSD license:
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * 3. Neither the name(s) of the above-listed copyright holder(s) nor the
+ *    names of its contributors may be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *    rc4.h
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   RC4 Engine
+ *
+ * Author:
+ * -------
+ * -------
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by ClearCase. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * $Log$
+ *
+ * 12 14 2010 leona.chou
+ * removed!
+ * .
+ *
+ * removed!
+ * removed!
+ * 
+ *
+ * removed!
+ * removed!
+ * add the speical case of RC4_SKIP to satisfy the WIFI 802.11i spec by skip the first 256 iteration of RC4.
+ *
+ * removed!
+ * removed!
+ * use a variable to record key schedule
+ *
+ * removed!
+ * removed!
+ * 
+ *
+ * removed!
+ * removed!
+ * 
+ *
+ * removed!
+ * removed!
+ * 
+ *
+ * removed!
+ * removed!
+ * Code revise.
+ *
+ * removed!
+ * removed!
+ * code review. add log placeholder.
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by ClearCase. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+#ifndef __RC4_H__
+#define __RC4_H__
+
+#include "che_api.h"
+
+#include "kal_general_types.h"
+
+#define S_SWAP(sa,sb) do { kal_uint8 t = sa; sa = sb; sb = t; } while(0)
+
+void che_rc4(RC4_CNXT *keySet,kal_uint8 *input, kal_uint32 len, kal_uint8 *key, kal_uint32 key_len, CHE_OPERATION_MODE mode, kal_uint8 *output);
+
+void che_rc4_set_key(RC4_CNXT *keySet, kal_uint32 len, kal_uint8 *data);
+
+#endif 
diff --git a/mcu/driver/che/include/sha.h b/mcu/driver/che/include/sha.h
new file mode 100644
index 0000000..1f0eb68
--- /dev/null
+++ b/mcu/driver/che/include/sha.h
@@ -0,0 +1,208 @@
+/* crypto/sha/sha.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+ /*****************************************************************************
+  *
+  * Filename:
+  * ---------
+  *    sha.h
+  *
+  * Project:
+  * --------
+  *   Maui_Software
+  *
+  * Description:
+  * ------------
+  *   SHA1 Engine
+  *
+  * Author:
+  * -------
+  *  Leona Chou (mtk01890)
+  *
+  *============================================================================
+  *             HISTORY
+  * Below this line, this part is controlled by ClearCase. DO NOT MODIFY!!
+  *------------------------------------------------------------------------------
+  * $Log$
+  *
+  * 11 26 2015 raymondwt.chen
+  * [MOLY00150233] [Jade] CHL and CHE design change
+  * .Remove sha1, md4, mac_sha1 from CHE and mark rsa tempararily
+  *
+  * 08 13 2015 raymondwt.chen
+  * [MOLY00137123] [UMOLY] Elbrus Che engine porting
+  * .Fix build error
+ *
+ * 03 16 2011 leona.chou
+ * removed!
+ * .
+  *
+  *------------------------------------------------------------------------------
+  * Upper this line, this part is controlled by ClearCase. DO NOT MODIFY!!
+  *============================================================================
+  ****************************************************************************/
+#ifndef HEADER_SHA_H
+#define HEADER_SHA_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#if defined(__LP32__)
+#define SHA_LONG unsigned long
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#define SHA_LONG unsigned long
+#define SHA_LONG_LOG2 3
+#else
+#define SHA_LONG unsigned int
+#endif
+
+//typedef unsigned int size_t;
+
+#define SHA_LBLOCK	16
+#define SHA_CBLOCK	(SHA_LBLOCK*4)	/* SHA treats input data as a
+					 * contiguous array of 32 bit
+					 * wide big-endian values. */
+#define SHA_LAST_BLOCK  (SHA_CBLOCK-8)
+#define SHA_DIGEST_LENGTH 20
+
+typedef struct SHAstate_st
+{
+    SHA_LONG h0,h1,h2,h3,h4;
+    SHA_LONG Nl,Nh;
+    SHA_LONG data[SHA_LBLOCK];
+    unsigned int num;
+} SHA_CTX;
+
+/*#ifndef OPENSSL_NO_SHA1
+int CHE_SHA1_Init(SHA_CTX *c);
+int CHE_SHA1_Update(SHA_CTX *c, const void *data, size_t len);
+int CHE_SHA1_Final(unsigned char *md, SHA_CTX *c);
+void CHE_SHA1_Transform(SHA_CTX *c, const unsigned char *data);
+#endif*/
+
+#define SHA256_CBLOCK	(SHA_LBLOCK*4)	/* SHA-256 treats input data as a
+					 * contiguous array of 32 bit
+					 * wide big-endian values. */
+#define SHA224_DIGEST_LENGTH	28
+#define SHA256_DIGEST_LENGTH	32
+
+typedef struct SHA256state_st
+{
+    SHA_LONG h[8];
+    SHA_LONG Nl,Nh;
+    SHA_LONG data[SHA_LBLOCK];
+    unsigned int num,md_len;
+} SHA256_CTX;
+
+#ifndef OPENSSL_NO_SHA256
+int CHE_SHA224_Init(SHA256_CTX *c);
+int CHE_SHA224_Update(SHA256_CTX *c, const void *data, size_t len);
+int CHE_SHA224_Final(unsigned char *md, SHA256_CTX *c);
+int CHE_SHA256_Init(SHA256_CTX *c);
+int CHE_SHA256_Update(SHA256_CTX *c, const void *data, size_t len);
+int CHE_SHA256_Final(unsigned char *md, SHA256_CTX *c);
+void CHE_SHA256_Transform(SHA256_CTX *c, const unsigned char *data);
+#endif
+
+#define SHA384_DIGEST_LENGTH	48
+#define SHA512_DIGEST_LENGTH	64
+
+#ifndef OPENSSL_NO_SHA512
+#define SHA512_CBLOCK	(SHA_LBLOCK*8)	/* SHA-512 treats input data as a
+					 * contiguous array of 64 bit
+					 * wide big-endian values. */
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
+#define SHA_LONG64 unsigned __int64
+#define U64(C)     C##UI64
+#elif defined(__arch64__)
+#define SHA_LONG64 unsigned long
+#define U64(C)     C##UL
+#else
+#define SHA_LONG64 unsigned long long
+#define U64(C)     C##ULL
+#endif
+
+typedef struct SHA512state_st
+{
+    SHA_LONG64 h[8];
+    SHA_LONG64 Nl,Nh;
+    union {
+        SHA_LONG64	d[SHA_LBLOCK];
+        unsigned char	p[SHA512_CBLOCK];
+    } u;
+    unsigned int num,md_len;
+} SHA512_CTX;
+#endif
+
+#ifndef OPENSSL_NO_SHA512
+int CHE_SHA384_Init(SHA512_CTX *c);
+int CHE_SHA384_Update(SHA512_CTX *c, const void *data, size_t len);
+int CHE_SHA384_Final(unsigned char *md, SHA512_CTX *c);
+unsigned char *CHE_SHA384(const unsigned char *d, size_t n,unsigned char *md);
+int CHE_SHA512_Init(SHA512_CTX *c);
+int CHE_SHA512_Update(SHA512_CTX *c, const void *data, size_t len);
+int CHE_SHA512_Final(unsigned char *md, SHA512_CTX *c);
+unsigned char *CHE_SHA512(const unsigned char *d, size_t n,unsigned char *md);
+void CHE_SHA512_Transform(SHA512_CTX *c, const unsigned char *data);
+#endif
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/mcu/driver/che/include/sha_locl.h b/mcu/driver/che/include/sha_locl.h
new file mode 100644
index 0000000..1687fca
--- /dev/null
+++ b/mcu/driver/che/include/sha_locl.h
@@ -0,0 +1,352 @@
+/* crypto/sha/sha_locl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+//#include <openssl/opensslconf.h>
+#include "sha.h"
+
+#define DATA_ORDER_IS_BIG_ENDIAN
+
+#define HASH_LONG               SHA_LONG
+#define HASH_CTX                SHA_CTX
+#define HASH_CBLOCK             SHA_CBLOCK
+#define HASH_MAKE_STRING(c,s)   do {	\
+	unsigned long ll;		\
+	ll=(c)->h0; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->h1; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->h2; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->h3; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->h4; (void)HOST_l2c(ll,(s));	\
+	} while (0)
+
+#if defined(SHA_0)
+
+# define HASH_UPDATE             	SHA_Update
+# define HASH_TRANSFORM          	SHA_Transform
+# define HASH_FINAL              	SHA_Final
+# define HASH_INIT			SHA_Init
+# define HASH_BLOCK_DATA_ORDER   	sha_block_data_order
+# define Xupdate(a,ix,ia,ib,ic,id)	(ix=(a)=(ia^ib^ic^id))
+
+static void sha_block_data_order (SHA_CTX *c, const void *p,size_t num);
+
+#elif defined(SHA_1)
+
+# define HASH_UPDATE             	SHA1_Update
+# define HASH_TRANSFORM          	SHA1_Transform
+# define HASH_FINAL              	SHA1_Final
+# define HASH_INIT			SHA1_Init
+# define HASH_BLOCK_DATA_ORDER   	sha1_block_data_order
+# if defined(__MWERKS__) && defined(__MC68K__)
+   /* Metrowerks for Motorola fails otherwise:-( <appro@fy.chalmers.se> */
+#  define Xupdate(a,ix,ia,ib,ic,id)	do { (a)=(ia^ib^ic^id);		\
+					     ix=(a)=ROTATE((a),1);	\
+					} while (0)
+# else
+#  define Xupdate(a,ix,ia,ib,ic,id)	( (a)=(ia^ib^ic^id),	\
+					  ix=(a)=ROTATE((a),1)	\
+					)
+# endif
+
+#ifndef SHA1_ASM
+static
+#endif
+void sha1_block_data_order (SHA_CTX *c, const void *p,size_t num);
+
+#else
+# error "Either SHA_0 or SHA_1 must be defined."
+#endif
+
+#include "md32_common.h"
+
+#define INIT_DATA_h0 0x67452301UL
+#define INIT_DATA_h1 0xefcdab89UL
+#define INIT_DATA_h2 0x98badcfeUL
+#define INIT_DATA_h3 0x10325476UL
+#define INIT_DATA_h4 0xc3d2e1f0UL
+
+#ifdef SHA_0
+fips_md_init(SHA)
+#else
+fips_md_init_ctx(SHA1, SHA)
+#endif
+{
+	memset (c,0,sizeof(*c));
+	c->h0=INIT_DATA_h0;
+	c->h1=INIT_DATA_h1;
+	c->h2=INIT_DATA_h2;
+	c->h3=INIT_DATA_h3;
+	c->h4=INIT_DATA_h4;
+	return 1;
+}
+
+#define K_00_19	0x5a827999UL
+#define K_20_39 0x6ed9eba1UL
+#define K_40_59 0x8f1bbcdcUL
+#define K_60_79 0xca62c1d6UL
+
+/* As  pointed out by Wei Dai <weidai@eskimo.com>, F() below can be
+ * simplified to the code in F_00_19.  Wei attributes these optimisations
+ * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
+ * #define F(x,y,z) (((x) & (y))  |  ((~(x)) & (z)))
+ * I've just become aware of another tweak to be made, again from Wei Dai,
+ * in F_40_59, (x&a)|(y&a) -> (x|y)&a
+ */
+#define	F_00_19(b,c,d)	((((c) ^ (d)) & (b)) ^ (d)) 
+#define	F_20_39(b,c,d)	((b) ^ (c) ^ (d))
+#define F_40_59(b,c,d)	(((b) & (c)) | (((b)|(c)) & (d))) 
+#define	F_60_79(b,c,d)	F_20_39(b,c,d)
+
+
+#define BODY_00_15(i,a,b,c,d,e,f,xi) \
+	(f)=xi+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#define BODY_16_19(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
+	Xupdate(f,xi,xa,xb,xc,xd); \
+	(f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#define BODY_20_31(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
+	Xupdate(f,xi,xa,xb,xc,xd); \
+	(f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#define BODY_32_39(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+	Xupdate(f,xa,xa,xb,xc,xd); \
+	(f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#define BODY_40_59(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+	Xupdate(f,xa,xa,xb,xc,xd); \
+	(f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#define BODY_60_79(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+	Xupdate(f,xa,xa,xb,xc,xd); \
+	(f)=xa+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \
+	(b)=ROTATE((b),30);
+
+#ifdef X
+#undef X
+#endif
+  /*
+   * Originally X was an array. As it's automatic it's natural
+   * to expect RISC compiler to accomodate at least part of it in
+   * the register bank, isn't it? Unfortunately not all compilers
+   * "find" this expectation reasonable:-( On order to make such
+   * compilers generate better code I replace X[] with a bunch of
+   * X0, X1, etc. See the function body below...
+   *					<appro@fy.chalmers.se>
+   */
+# define X(i)	XX##i
+
+
+#if !defined(SHA_1) || !defined(SHA1_ASM)
+static void HASH_BLOCK_DATA_ORDER (SHA_CTX *c, const void *p, size_t num)
+	{
+	const unsigned char *data=p;
+	register unsigned MD32_REG_T A,B,C,D,E,T,l;
+
+	unsigned MD32_REG_T	XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+				XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
+
+	A=c->h0;
+	B=c->h1;
+	C=c->h2;
+	D=c->h3;
+	E=c->h4;
+
+	for (;;)
+			{
+	const union { long one; char little; } is_endian = {1};
+
+	if (!is_endian.little && sizeof(SHA_LONG)==4 && ((size_t)p%4)==0)
+		{
+		const SHA_LONG *W=(const SHA_LONG *)data;
+
+		X( 0) = W[0];				X( 1) = W[ 1];
+		BODY_00_15( 0,A,B,C,D,E,T,X( 0));	X( 2) = W[ 2];
+		BODY_00_15( 1,T,A,B,C,D,E,X( 1));	X( 3) = W[ 3];
+		BODY_00_15( 2,E,T,A,B,C,D,X( 2));	X( 4) = W[ 4];
+		BODY_00_15( 3,D,E,T,A,B,C,X( 3));	X( 5) = W[ 5];
+		BODY_00_15( 4,C,D,E,T,A,B,X( 4));	X( 6) = W[ 6];
+		BODY_00_15( 5,B,C,D,E,T,A,X( 5));	X( 7) = W[ 7];
+		BODY_00_15( 6,A,B,C,D,E,T,X( 6));	X( 8) = W[ 8];
+		BODY_00_15( 7,T,A,B,C,D,E,X( 7));	X( 9) = W[ 9];
+		BODY_00_15( 8,E,T,A,B,C,D,X( 8));	X(10) = W[10];
+		BODY_00_15( 9,D,E,T,A,B,C,X( 9));	X(11) = W[11];
+		BODY_00_15(10,C,D,E,T,A,B,X(10));	X(12) = W[12];
+		BODY_00_15(11,B,C,D,E,T,A,X(11));	X(13) = W[13];
+		BODY_00_15(12,A,B,C,D,E,T,X(12));	X(14) = W[14];
+		BODY_00_15(13,T,A,B,C,D,E,X(13));	X(15) = W[15];
+		BODY_00_15(14,E,T,A,B,C,D,X(14));
+		BODY_00_15(15,D,E,T,A,B,C,X(15));
+
+		data += SHA_CBLOCK;
+		}
+	else
+		{
+		(void)HOST_c2l(data,l); X( 0)=l;	(void)HOST_c2l(data,l); X( 1)=l;
+		BODY_00_15( 0,A,B,C,D,E,T,X( 0));	(void)HOST_c2l(data,l); X( 2)=l;
+		BODY_00_15( 1,T,A,B,C,D,E,X( 1));	(void)HOST_c2l(data,l); X( 3)=l;
+		BODY_00_15( 2,E,T,A,B,C,D,X( 2));	(void)HOST_c2l(data,l); X( 4)=l;
+		BODY_00_15( 3,D,E,T,A,B,C,X( 3));	(void)HOST_c2l(data,l); X( 5)=l;
+		BODY_00_15( 4,C,D,E,T,A,B,X( 4));	(void)HOST_c2l(data,l); X( 6)=l;
+		BODY_00_15( 5,B,C,D,E,T,A,X( 5));	(void)HOST_c2l(data,l); X( 7)=l;
+		BODY_00_15( 6,A,B,C,D,E,T,X( 6));	(void)HOST_c2l(data,l); X( 8)=l;
+		BODY_00_15( 7,T,A,B,C,D,E,X( 7));	(void)HOST_c2l(data,l); X( 9)=l;
+		BODY_00_15( 8,E,T,A,B,C,D,X( 8));	(void)HOST_c2l(data,l); X(10)=l;
+		BODY_00_15( 9,D,E,T,A,B,C,X( 9));	(void)HOST_c2l(data,l); X(11)=l;
+		BODY_00_15(10,C,D,E,T,A,B,X(10));	(void)HOST_c2l(data,l); X(12)=l;
+		BODY_00_15(11,B,C,D,E,T,A,X(11));	(void)HOST_c2l(data,l); X(13)=l;
+		BODY_00_15(12,A,B,C,D,E,T,X(12));	(void)HOST_c2l(data,l); X(14)=l;
+		BODY_00_15(13,T,A,B,C,D,E,X(13));	(void)HOST_c2l(data,l); X(15)=l;
+		BODY_00_15(14,E,T,A,B,C,D,X(14));
+		BODY_00_15(15,D,E,T,A,B,C,X(15));
+		}
+
+	BODY_16_19(16,C,D,E,T,A,B,X( 0),X( 0),X( 2),X( 8),X(13));
+	BODY_16_19(17,B,C,D,E,T,A,X( 1),X( 1),X( 3),X( 9),X(14));
+	BODY_16_19(18,A,B,C,D,E,T,X( 2),X( 2),X( 4),X(10),X(15));
+	BODY_16_19(19,T,A,B,C,D,E,X( 3),X( 3),X( 5),X(11),X( 0));
+
+	BODY_20_31(20,E,T,A,B,C,D,X( 4),X( 4),X( 6),X(12),X( 1));
+	BODY_20_31(21,D,E,T,A,B,C,X( 5),X( 5),X( 7),X(13),X( 2));
+	BODY_20_31(22,C,D,E,T,A,B,X( 6),X( 6),X( 8),X(14),X( 3));
+	BODY_20_31(23,B,C,D,E,T,A,X( 7),X( 7),X( 9),X(15),X( 4));
+	BODY_20_31(24,A,B,C,D,E,T,X( 8),X( 8),X(10),X( 0),X( 5));
+	BODY_20_31(25,T,A,B,C,D,E,X( 9),X( 9),X(11),X( 1),X( 6));
+	BODY_20_31(26,E,T,A,B,C,D,X(10),X(10),X(12),X( 2),X( 7));
+	BODY_20_31(27,D,E,T,A,B,C,X(11),X(11),X(13),X( 3),X( 8));
+	BODY_20_31(28,C,D,E,T,A,B,X(12),X(12),X(14),X( 4),X( 9));
+	BODY_20_31(29,B,C,D,E,T,A,X(13),X(13),X(15),X( 5),X(10));
+	BODY_20_31(30,A,B,C,D,E,T,X(14),X(14),X( 0),X( 6),X(11));
+	BODY_20_31(31,T,A,B,C,D,E,X(15),X(15),X( 1),X( 7),X(12));
+
+	BODY_32_39(32,E,T,A,B,C,D,X( 0),X( 2),X( 8),X(13));
+	BODY_32_39(33,D,E,T,A,B,C,X( 1),X( 3),X( 9),X(14));
+	BODY_32_39(34,C,D,E,T,A,B,X( 2),X( 4),X(10),X(15));
+	BODY_32_39(35,B,C,D,E,T,A,X( 3),X( 5),X(11),X( 0));
+	BODY_32_39(36,A,B,C,D,E,T,X( 4),X( 6),X(12),X( 1));
+	BODY_32_39(37,T,A,B,C,D,E,X( 5),X( 7),X(13),X( 2));
+	BODY_32_39(38,E,T,A,B,C,D,X( 6),X( 8),X(14),X( 3));
+	BODY_32_39(39,D,E,T,A,B,C,X( 7),X( 9),X(15),X( 4));
+
+	BODY_40_59(40,C,D,E,T,A,B,X( 8),X(10),X( 0),X( 5));
+	BODY_40_59(41,B,C,D,E,T,A,X( 9),X(11),X( 1),X( 6));
+	BODY_40_59(42,A,B,C,D,E,T,X(10),X(12),X( 2),X( 7));
+	BODY_40_59(43,T,A,B,C,D,E,X(11),X(13),X( 3),X( 8));
+	BODY_40_59(44,E,T,A,B,C,D,X(12),X(14),X( 4),X( 9));
+	BODY_40_59(45,D,E,T,A,B,C,X(13),X(15),X( 5),X(10));
+	BODY_40_59(46,C,D,E,T,A,B,X(14),X( 0),X( 6),X(11));
+	BODY_40_59(47,B,C,D,E,T,A,X(15),X( 1),X( 7),X(12));
+	BODY_40_59(48,A,B,C,D,E,T,X( 0),X( 2),X( 8),X(13));
+	BODY_40_59(49,T,A,B,C,D,E,X( 1),X( 3),X( 9),X(14));
+	BODY_40_59(50,E,T,A,B,C,D,X( 2),X( 4),X(10),X(15));
+	BODY_40_59(51,D,E,T,A,B,C,X( 3),X( 5),X(11),X( 0));
+	BODY_40_59(52,C,D,E,T,A,B,X( 4),X( 6),X(12),X( 1));
+	BODY_40_59(53,B,C,D,E,T,A,X( 5),X( 7),X(13),X( 2));
+	BODY_40_59(54,A,B,C,D,E,T,X( 6),X( 8),X(14),X( 3));
+	BODY_40_59(55,T,A,B,C,D,E,X( 7),X( 9),X(15),X( 4));
+	BODY_40_59(56,E,T,A,B,C,D,X( 8),X(10),X( 0),X( 5));
+	BODY_40_59(57,D,E,T,A,B,C,X( 9),X(11),X( 1),X( 6));
+	BODY_40_59(58,C,D,E,T,A,B,X(10),X(12),X( 2),X( 7));
+	BODY_40_59(59,B,C,D,E,T,A,X(11),X(13),X( 3),X( 8));
+
+	BODY_60_79(60,A,B,C,D,E,T,X(12),X(14),X( 4),X( 9));
+	BODY_60_79(61,T,A,B,C,D,E,X(13),X(15),X( 5),X(10));
+	BODY_60_79(62,E,T,A,B,C,D,X(14),X( 0),X( 6),X(11));
+	BODY_60_79(63,D,E,T,A,B,C,X(15),X( 1),X( 7),X(12));
+	BODY_60_79(64,C,D,E,T,A,B,X( 0),X( 2),X( 8),X(13));
+	BODY_60_79(65,B,C,D,E,T,A,X( 1),X( 3),X( 9),X(14));
+	BODY_60_79(66,A,B,C,D,E,T,X( 2),X( 4),X(10),X(15));
+	BODY_60_79(67,T,A,B,C,D,E,X( 3),X( 5),X(11),X( 0));
+	BODY_60_79(68,E,T,A,B,C,D,X( 4),X( 6),X(12),X( 1));
+	BODY_60_79(69,D,E,T,A,B,C,X( 5),X( 7),X(13),X( 2));
+	BODY_60_79(70,C,D,E,T,A,B,X( 6),X( 8),X(14),X( 3));
+	BODY_60_79(71,B,C,D,E,T,A,X( 7),X( 9),X(15),X( 4));
+	BODY_60_79(72,A,B,C,D,E,T,X( 8),X(10),X( 0),X( 5));
+	BODY_60_79(73,T,A,B,C,D,E,X( 9),X(11),X( 1),X( 6));
+	BODY_60_79(74,E,T,A,B,C,D,X(10),X(12),X( 2),X( 7));
+	BODY_60_79(75,D,E,T,A,B,C,X(11),X(13),X( 3),X( 8));
+	BODY_60_79(76,C,D,E,T,A,B,X(12),X(14),X( 4),X( 9));
+	BODY_60_79(77,B,C,D,E,T,A,X(13),X(15),X( 5),X(10));
+	BODY_60_79(78,A,B,C,D,E,T,X(14),X( 0),X( 6),X(11));
+	BODY_60_79(79,T,A,B,C,D,E,X(15),X( 1),X( 7),X(12));
+	
+	c->h0=(c->h0+E)&0xffffffffL; 
+	c->h1=(c->h1+T)&0xffffffffL;
+	c->h2=(c->h2+A)&0xffffffffL;
+	c->h3=(c->h3+B)&0xffffffffL;
+	c->h4=(c->h4+C)&0xffffffffL;
+
+	if (--num == 0) break;
+
+	A=c->h0;
+	B=c->h1;
+	C=c->h2;
+	D=c->h3;
+	E=c->h4;
+
+			}
+	}
+#endif
+