├── .gitignore ├── LICENSE ├── README.md ├── SConscript ├── include ├── tiny_aes.h ├── tiny_base64.h ├── tiny_md5.h ├── tiny_sha1.h ├── tiny_sha2.h ├── tinycrypt.h └── tinycrypt_config.h ├── samples ├── aes_sample.c └── md5_sample.c └── src ├── tiny_aes.c ├── tiny_base64.c ├── tiny_md5.c ├── tiny_sha1.c └── tiny_sha2.c /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2017, The packages repositories of RT-Thread. 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tinycrypt 2 | 3 | A simple and configurable crypt library 4 | -------------------------------------------------------------------------------- /SConscript: -------------------------------------------------------------------------------- 1 | # RT-Thread building script for component 2 | 3 | from building import * 4 | 5 | cwd = GetCurrentDir() 6 | src = Glob('src/*.c') + Glob('src/*.cpp') 7 | CPPPATH = [cwd + '/include'] 8 | 9 | if GetDepend(['TINYCRYPT_USING_AES_SAMPLE']): 10 | src += Glob('samples/aes_sample.c') 11 | 12 | if GetDepend(['TINYCRYPT_USING_MD5_SAMPLE']): 13 | src += Glob('samples/md5_sample.c') 14 | 15 | group = DefineGroup('TinyCrypt', src, depend = ['PKG_USING_TINYCRYPT'], CPPPATH = CPPPATH) 16 | 17 | Return('group') 18 | -------------------------------------------------------------------------------- /include/tiny_aes.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file aes.h 3 | * 4 | * Based on TropicSSL: Copyright (C) 2017 Shanghai Real-Thread Technology Co., Ltd 5 | * 6 | * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine 7 | * 8 | * Copyright (C) 2009 Paul Bakker 9 | * 10 | * All rights reserved. 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions 14 | * are met: 15 | * 16 | * * Redistributions of source code must retain the above copyright 17 | * notice, this list of conditions and the following disclaimer. 18 | * * Redistributions in binary form must reproduce the above copyright 19 | * notice, this list of conditions and the following disclaimer in the 20 | * documentation and/or other materials provided with the distribution. 21 | * * Neither the names of PolarSSL or XySSL nor the names of its contributors 22 | * may be used to endorse or promote products derived from this software 23 | * without specific prior written permission. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 28 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 31 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | */ 37 | #ifndef TINY_CRYPT_AES_H__ 38 | #define TINY_CRYPT_AES_H__ 39 | 40 | #define AES_ENCRYPT 1 41 | #define AES_DECRYPT 0 42 | 43 | /** 44 | * \brief AES context structure 45 | */ 46 | typedef struct { 47 | int nr; /*!< number of rounds */ 48 | uint32_t *rk; /*!< AES round keys */ 49 | uint32_t buf[68]; /*!< unaligned data */ 50 | } tiny_aes_context; 51 | 52 | #ifdef __cplusplus 53 | extern "C" { 54 | #endif 55 | 56 | /** 57 | * \brief AES key schedule (encryption) 58 | * 59 | * \param ctx AES context to be initialized 60 | * \param key encryption key 61 | * \param keysize must be 128, 192 or 256 62 | */ 63 | void tiny_aes_setkey_enc(tiny_aes_context * ctx, uint8_t *key, int keysize); 64 | 65 | /** 66 | * \brief AES key schedule (decryption) 67 | * 68 | * \param ctx AES context to be initialized 69 | * \param key decryption key 70 | * \param keysize must be 128, 192 or 256 71 | */ 72 | void tiny_aes_setkey_dec(tiny_aes_context * ctx, uint8_t *key, int keysize); 73 | 74 | /** 75 | * \brief AES-ECB block encryption/decryption 76 | * 77 | * \param ctx AES context 78 | * \param mode AES_ENCRYPT or AES_DECRYPT 79 | * \param input 16-byte input block 80 | * \param output 16-byte output block 81 | */ 82 | void tiny_aes_crypt_ecb(tiny_aes_context * ctx, 83 | int mode, 84 | uint8_t input[16], uint8_t output[16]); 85 | 86 | /** 87 | * \brief AES-CBC buffer encryption/decryption 88 | * 89 | * \param ctx AES context 90 | * \param mode AES_ENCRYPT or AES_DECRYPT 91 | * \param length length of the input data 92 | * \param iv initialization vector (updated after use) 93 | * \param input buffer holding the input data 94 | * \param output buffer holding the output data 95 | */ 96 | void tiny_aes_crypt_cbc(tiny_aes_context * ctx, 97 | int mode, 98 | int length, 99 | uint8_t iv[16], 100 | uint8_t *input, uint8_t *output); 101 | 102 | /** 103 | * \brief AES-CFB128 buffer encryption/decryption 104 | * 105 | * \param ctx AES context 106 | * \param mode AES_ENCRYPT or AES_DECRYPT 107 | * \param length length of the input data 108 | * \param iv_off offset in IV (updated after use) 109 | * \param iv initialization vector (updated after use) 110 | * \param input buffer holding the input data 111 | * \param output buffer holding the output data 112 | */ 113 | void tiny_aes_crypt_cfb128(tiny_aes_context * ctx, 114 | int mode, 115 | int length, 116 | int *iv_off, 117 | uint8_t iv[16], 118 | uint8_t *input, uint8_t *output); 119 | 120 | #ifdef __cplusplus 121 | } 122 | #endif 123 | #endif /* aes.h */ 124 | -------------------------------------------------------------------------------- /include/tiny_base64.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file base64.h 3 | * 4 | * Based on TropicSSL: Copyright (C) 2017 Shanghai Real-Thread Technology Co., Ltd 5 | * 6 | * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine 7 | * 8 | * Copyright (C) 2009 Paul Bakker 9 | * 10 | * All rights reserved. 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions 14 | * are met: 15 | * 16 | * * Redistributions of source code must retain the above copyright 17 | * notice, this list of conditions and the following disclaimer. 18 | * * Redistributions in binary form must reproduce the above copyright 19 | * notice, this list of conditions and the following disclaimer in the 20 | * documentation and/or other materials provided with the distribution. 21 | * * Neither the names of PolarSSL or XySSL nor the names of its contributors 22 | * may be used to endorse or promote products derived from this software 23 | * without specific prior written permission. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 28 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 31 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | */ 37 | #ifndef TINY_CRYPT_BASE64_H__ 38 | #define TINY_CRYPT_BASE64_H__ 39 | 40 | #define ERR_BASE64_BUFFER_TOO_SMALL -0x0010 41 | #define ERR_BASE64_INVALID_CHARACTER -0x0012 42 | 43 | #ifdef __cplusplus 44 | extern "C" { 45 | #endif 46 | 47 | /** 48 | * \brief Encode a buffer into base64 format 49 | * 50 | * \param dst destination buffer 51 | * \param dlen size of the buffer 52 | * \param src source buffer 53 | * \param slen amount of data to be encoded 54 | * 55 | * \return 0 if successful, or TROPICSSL_ERR_BASE64_BUFFER_TOO_SMALL. 56 | * *dlen is always updated to reflect the amount 57 | * of data that has (or would have) been written. 58 | * 59 | * \note Call this function with *dlen = 0 to obtain the 60 | * required buffer size in *dlen 61 | */ 62 | int tiny_base64_encode(uint8_t *dst, int *dlen, 63 | uint8_t *src, int slen); 64 | 65 | /** 66 | * \brief Decode a base64-formatted buffer 67 | * 68 | * \param dst destination buffer 69 | * \param dlen size of the buffer 70 | * \param src source buffer 71 | * \param slen amount of data to be decoded 72 | * 73 | * \return 0 if successful, TROPICSSL_ERR_BASE64_BUFFER_TOO_SMALL, or 74 | * TROPICSSL_ERR_BASE64_INVALID_DATA if the input data is not 75 | * correct. *dlen is always updated to reflect the amount 76 | * of data that has (or would have) been written. 77 | * 78 | * \note Call this function with *dlen = 0 to obtain the 79 | * required buffer size in *dlen 80 | */ 81 | int tiny_base64_decode(uint8_t *dst, int *dlen, 82 | uint8_t *src, int slen); 83 | 84 | #ifdef __cplusplus 85 | } 86 | #endif 87 | #endif /* base64.h */ 88 | -------------------------------------------------------------------------------- /include/tiny_md5.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file md5.h 3 | * 4 | * Based on TropicSSL: Copyright (C) 2017 Shanghai Real-Thread Technology Co., Ltd 5 | * 6 | * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine 7 | * 8 | * Copyright (C) 2009 Paul Bakker 9 | * 10 | * All rights reserved. 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions 14 | * are met: 15 | * 16 | * * Redistributions of source code must retain the above copyright 17 | * notice, this list of conditions and the following disclaimer. 18 | * * Redistributions in binary form must reproduce the above copyright 19 | * notice, this list of conditions and the following disclaimer in the 20 | * documentation and/or other materials provided with the distribution. 21 | * * Neither the names of PolarSSL or XySSL nor the names of its contributors 22 | * may be used to endorse or promote products derived from this software 23 | * without specific prior written permission. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 28 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 31 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | */ 37 | #ifndef TINY_CRYPT_MD5_H__ 38 | #define TINY_CRYPT_MD5_H__ 39 | 40 | /** 41 | * \brief MD5 context structure 42 | */ 43 | typedef struct { 44 | uint32_t total[2]; /*!< number of bytes processed */ 45 | uint32_t state[4]; /*!< intermediate digest state */ 46 | uint8_t buffer[64]; /*!< data block being processed */ 47 | 48 | uint8_t ipad[64]; /*!< HMAC: inner padding */ 49 | uint8_t opad[64]; /*!< HMAC: outer padding */ 50 | } tiny_md5_context; 51 | 52 | #ifdef __cplusplus 53 | extern "C" { 54 | #endif 55 | 56 | /** 57 | * \brief MD5 context setup 58 | * 59 | * \param ctx context to be initialized 60 | */ 61 | void tiny_md5_starts(tiny_md5_context * ctx); 62 | 63 | /** 64 | * \brief MD5 process buffer 65 | * 66 | * \param ctx MD5 context 67 | * \param input buffer holding the data 68 | * \param ilen length of the input data 69 | */ 70 | void tiny_md5_update(tiny_md5_context * ctx, uint8_t *input, int ilen); 71 | 72 | /** 73 | * \brief MD5 final digest 74 | * 75 | * \param ctx MD5 context 76 | * \param output MD5 checksum result 77 | */ 78 | void tiny_md5_finish(tiny_md5_context * ctx, uint8_t output[16]); 79 | 80 | /** 81 | * \brief Output = MD5( input buffer ) 82 | * 83 | * \param input buffer holding the data 84 | * \param ilen length of the input data 85 | * \param output MD5 checksum result 86 | */ 87 | void tiny_md5(uint8_t *input, int ilen, uint8_t output[16]); 88 | 89 | /** 90 | * \brief MD5 HMAC context setup 91 | * 92 | * \param ctx HMAC context to be initialized 93 | * \param key HMAC secret key 94 | * \param keylen length of the HMAC key 95 | */ 96 | void tiny_md5_hmac_starts(tiny_md5_context * ctx, uint8_t *key, int keylen); 97 | 98 | /** 99 | * \brief MD5 HMAC process buffer 100 | * 101 | * \param ctx HMAC context 102 | * \param input buffer holding the data 103 | * \param ilen length of the input data 104 | */ 105 | void tiny_md5_hmac_update(tiny_md5_context * ctx, uint8_t *input, int ilen); 106 | 107 | /** 108 | * \brief MD5 HMAC final digest 109 | * 110 | * \param ctx HMAC context 111 | * \param output MD5 HMAC checksum result 112 | */ 113 | void tiny_md5_hmac_finish(tiny_md5_context * ctx, uint8_t output[16]); 114 | 115 | /** 116 | * \brief Output = HMAC-MD5( hmac key, input buffer ) 117 | * 118 | * \param key HMAC secret key 119 | * \param keylen length of the HMAC key 120 | * \param input buffer holding the data 121 | * \param ilen length of the input data 122 | * \param output HMAC-MD5 result 123 | */ 124 | void tiny_md5_hmac(uint8_t *key, int keylen, 125 | uint8_t *input, int ilen, uint8_t output[16]); 126 | 127 | #ifdef __cplusplus 128 | } 129 | #endif 130 | #endif /* md5.h */ 131 | -------------------------------------------------------------------------------- /include/tiny_sha1.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file sha1.h 3 | * 4 | * Based on TropicSSL: Copyright (C) 2017 Shanghai Real-Thread Technology Co., Ltd 5 | * 6 | * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine 7 | * 8 | * Copyright (C) 2009 Paul Bakker 9 | * 10 | * All rights reserved. 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions 14 | * are met: 15 | * 16 | * * Redistributions of source code must retain the above copyright 17 | * notice, this list of conditions and the following disclaimer. 18 | * * Redistributions in binary form must reproduce the above copyright 19 | * notice, this list of conditions and the following disclaimer in the 20 | * documentation and/or other materials provided with the distribution. 21 | * * Neither the names of PolarSSL or XySSL nor the names of its contributors 22 | * may be used to endorse or promote products derived from this software 23 | * without specific prior written permission. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 28 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 31 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | */ 37 | #ifndef TINY_CRYPT_SHA1_H__ 38 | #define TINY_CRYPT_SHA1_H__ 39 | 40 | /** 41 | * \brief SHA-1 context structure 42 | */ 43 | typedef struct { 44 | uint32_t total[2]; /*!< number of bytes processed */ 45 | uint32_t state[5]; /*!< intermediate digest state */ 46 | uint8_t buffer[64]; /*!< data block being processed */ 47 | 48 | uint8_t ipad[64]; /*!< HMAC: inner padding */ 49 | uint8_t opad[64]; /*!< HMAC: outer padding */ 50 | } tiny_sha1_context; 51 | 52 | #ifdef __cplusplus 53 | extern "C" { 54 | #endif 55 | 56 | /** 57 | * \brief SHA-1 context setup 58 | * 59 | * \param ctx context to be initialized 60 | */ 61 | void tiny_sha1_starts(tiny_sha1_context * ctx); 62 | 63 | /** 64 | * \brief SHA-1 process buffer 65 | * 66 | * \param ctx SHA-1 context 67 | * \param input buffer holding the data 68 | * \param ilen length of the input data 69 | */ 70 | void tiny_sha1_update(tiny_sha1_context * ctx, uint8_t *input, int ilen); 71 | 72 | /** 73 | * \brief SHA-1 final digest 74 | * 75 | * \param ctx SHA-1 context 76 | * \param output SHA-1 checksum result 77 | */ 78 | void tiny_sha1_finish(tiny_sha1_context * ctx, uint8_t output[20]); 79 | 80 | /** 81 | * \brief Output = SHA-1( input buffer ) 82 | * 83 | * \param input buffer holding the data 84 | * \param ilen length of the input data 85 | * \param output SHA-1 checksum result 86 | */ 87 | void tiny_sha1(uint8_t *input, int ilen, uint8_t output[20]); 88 | 89 | /** 90 | * \brief SHA-1 HMAC context setup 91 | * 92 | * \param ctx HMAC context to be initialized 93 | * \param key HMAC secret key 94 | * \param keylen length of the HMAC key 95 | */ 96 | void tiny_sha1_hmac_starts(tiny_sha1_context * ctx, uint8_t *key, 97 | int keylen); 98 | 99 | /** 100 | * \brief SHA-1 HMAC process buffer 101 | * 102 | * \param ctx HMAC context 103 | * \param input buffer holding the data 104 | * \param ilen length of the input data 105 | */ 106 | void tiny_sha1_hmac_update(tiny_sha1_context * ctx, uint8_t *input, 107 | int ilen); 108 | 109 | /** 110 | * \brief SHA-1 HMAC final digest 111 | * 112 | * \param ctx HMAC context 113 | * \param output SHA-1 HMAC checksum result 114 | */ 115 | void tiny_sha1_hmac_finish(tiny_sha1_context * ctx, uint8_t output[20]); 116 | 117 | /** 118 | * \brief Output = HMAC-SHA-1( hmac key, input buffer ) 119 | * 120 | * \param key HMAC secret key 121 | * \param keylen length of the HMAC key 122 | * \param input buffer holding the data 123 | * \param ilen length of the input data 124 | * \param output HMAC-SHA-1 result 125 | */ 126 | void tiny_sha1_hmac(uint8_t *key, int keylen, 127 | uint8_t *input, int ilen, 128 | uint8_t output[20]); 129 | 130 | #ifdef __cplusplus 131 | } 132 | #endif 133 | #endif /* sha1.h */ 134 | -------------------------------------------------------------------------------- /include/tiny_sha2.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file sha2.h 3 | * 4 | * Based on TropicSSL: Copyright (C) 2017 Shanghai Real-Thread Technology Co., Ltd 5 | * 6 | * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine 7 | * 8 | * Copyright (C) 2009 Paul Bakker 9 | * 10 | * All rights reserved. 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions 14 | * are met: 15 | * 16 | * * Redistributions of source code must retain the above copyright 17 | * notice, this list of conditions and the following disclaimer. 18 | * * Redistributions in binary form must reproduce the above copyright 19 | * notice, this list of conditions and the following disclaimer in the 20 | * documentation and/or other materials provided with the distribution. 21 | * * Neither the names of PolarSSL or XySSL nor the names of its contributors 22 | * may be used to endorse or promote products derived from this software 23 | * without specific prior written permission. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 28 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 31 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | */ 37 | #ifndef TINY_CRYPT_SHA2_H__ 38 | #define TINY_CRYPT_SHA2_H__ 39 | 40 | /** 41 | * \brief SHA-256 context structure 42 | */ 43 | typedef struct { 44 | uint32_t total[2]; /*!< number of bytes processed */ 45 | uint32_t state[8]; /*!< intermediate digest state */ 46 | uint8_t buffer[64]; /*!< data block being processed */ 47 | 48 | uint8_t ipad[64]; /*!< HMAC: inner padding */ 49 | uint8_t opad[64]; /*!< HMAC: outer padding */ 50 | int is224; /*!< 0 => SHA-256, else SHA-224 */ 51 | } tiny_sha2_context; 52 | 53 | #ifdef __cplusplus 54 | extern "C" { 55 | #endif 56 | 57 | /** 58 | * \brief SHA-256 context setup 59 | * 60 | * \param ctx context to be initialized 61 | * \param is224 0 = use SHA256, 1 = use SHA224 62 | */ 63 | void tiny_sha2_starts(tiny_sha2_context * ctx, int is224); 64 | 65 | /** 66 | * \brief SHA-256 process buffer 67 | * 68 | * \param ctx SHA-256 context 69 | * \param input buffer holding the data 70 | * \param ilen length of the input data 71 | */ 72 | void tiny_sha2_update(tiny_sha2_context * ctx, uint8_t *input, int ilen); 73 | 74 | /** 75 | * \brief SHA-256 final digest 76 | * 77 | * \param ctx SHA-256 context 78 | * \param output SHA-224/256 checksum result 79 | */ 80 | void tiny_sha2_finish(tiny_sha2_context * ctx, uint8_t output[32]); 81 | 82 | /** 83 | * \brief Output = SHA-256( input buffer ) 84 | * 85 | * \param input buffer holding the data 86 | * \param ilen length of the input data 87 | * \param output SHA-224/256 checksum result 88 | * \param is224 0 = use SHA256, 1 = use SHA224 89 | */ 90 | void tiny_sha2(uint8_t *input, int ilen, 91 | uint8_t output[32], int is224); 92 | 93 | /** 94 | * \brief SHA-256 HMAC context setup 95 | * 96 | * \param ctx HMAC context to be initialized 97 | * \param key HMAC secret key 98 | * \param keylen length of the HMAC key 99 | * \param is224 0 = use SHA256, 1 = use SHA224 100 | */ 101 | void tiny_sha2_hmac_starts(tiny_sha2_context * ctx, uint8_t *key, 102 | int keylen, int is224); 103 | 104 | /** 105 | * \brief SHA-256 HMAC process buffer 106 | * 107 | * \param ctx HMAC context 108 | * \param input buffer holding the data 109 | * \param ilen length of the input data 110 | */ 111 | void tiny_sha2_hmac_update(tiny_sha2_context * ctx, uint8_t *input, 112 | int ilen); 113 | 114 | /** 115 | * \brief SHA-256 HMAC final digest 116 | * 117 | * \param ctx HMAC context 118 | * \param output SHA-224/256 HMAC checksum result 119 | */ 120 | void tiny_sha2_hmac_finish(tiny_sha2_context * ctx, uint8_t output[32]); 121 | 122 | /** 123 | * \brief Output = HMAC-SHA-256( hmac key, input buffer ) 124 | * 125 | * \param key HMAC secret key 126 | * \param keylen length of the HMAC key 127 | * \param input buffer holding the data 128 | * \param ilen length of the input data 129 | * \param output HMAC-SHA-224/256 result 130 | * \param is224 0 = use SHA256, 1 = use SHA224 131 | */ 132 | void tiny_sha2_hmac(uint8_t *key, int keylen, 133 | uint8_t *input, int ilen, 134 | uint8_t output[32], int is224); 135 | 136 | #ifdef __cplusplus 137 | } 138 | #endif 139 | #endif /* sha2.h */ 140 | -------------------------------------------------------------------------------- /include/tinycrypt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File : tinycrypt.h 3 | * This file is part of Tiny Crypt library 4 | * COPYRIGHT (C) 2017, Shanghai Real-Thread Technology Co., Ltd 5 | * 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 12 | * * Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * * Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * * Neither the names of PolarSSL or XySSL nor the names of its contributors 18 | * may be used to endorse or promote products derived from this software 19 | * without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | * Change Logs: 34 | * Date Author Notes 35 | * 2017-12-02 RealThread the first version 36 | */ 37 | 38 | #ifndef TINY_CRYPT_H__ 39 | #define TINY_CRYPT_H__ 40 | 41 | #ifdef TINY_CRYPT_MD5 42 | #include "tiny_md5.h" 43 | #endif 44 | 45 | #ifdef TINY_CRYPT_AES 46 | #include "tiny_aes.h" 47 | #endif 48 | 49 | #ifdef TINY_CRYPT_SHA1 50 | #include "tiny_sha1.h" 51 | #endif 52 | 53 | #ifdef TINY_CRYPT_SHA256 54 | #include "tiny_sha2.h" 55 | #endif 56 | 57 | #ifdef TINY_CRYPT_BASE64 58 | #include "tiny_base64.h" 59 | #endif 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /include/tinycrypt_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File : tinycrypt_config.h 3 | * This file is part of Tiny Crypt library 4 | * COPYRIGHT (C) 2017, Shanghai Real-Thread Technology Co., Ltd 5 | * 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 12 | * * Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * * Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * * Neither the names of PolarSSL or XySSL nor the names of its contributors 18 | * may be used to endorse or promote products derived from this software 19 | * without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | * Change Logs: 34 | * Date Author Notes 35 | * 2017-12-02 RealThread the first version 36 | */ 37 | 38 | #ifndef TINY_CRYPT_CONFIG_H__ 39 | #define TINY_CRYPT_CONFIG_H__ 40 | 41 | #include 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /samples/aes_sample.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2021, RT-Thread Development Team 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | * 6 | * Change Logs: 7 | * Date Author Notes 8 | * 2019-03-22 MurphyZhao the first version 9 | */ 10 | 11 | #include 12 | 13 | #include 14 | 15 | #define TEST_TINY_AES_IV "0123456789ABCDEF" 16 | #define TEST_TINY_AES_KEY "0123456789ABCDEF0123456789ABCDEF" 17 | 18 | static rt_err_t test_tiny_aes(void) 19 | { 20 | tiny_aes_context ctx; 21 | uint8_t iv[16 + 1]; 22 | uint8_t private_key[32 + 1]; 23 | 24 | uint8_t data[] = "1234567890123456"; 25 | uint8_t data_encrypt[32]; 26 | uint8_t data_decrypt[32]; 27 | 28 | /* encrypt */ 29 | rt_memcpy(iv, TEST_TINY_AES_IV, rt_strlen(TEST_TINY_AES_IV)); 30 | iv[sizeof(iv) - 1] = '\0'; 31 | rt_memcpy(private_key, TEST_TINY_AES_KEY, rt_strlen(TEST_TINY_AES_KEY)); 32 | private_key[sizeof(private_key) - 1] = '\0'; 33 | 34 | rt_memset(data_encrypt, 0x0, sizeof(data_encrypt)); 35 | tiny_aes_setkey_enc(&ctx, (uint8_t *) private_key, 256); 36 | tiny_aes_crypt_cbc(&ctx, AES_ENCRYPT, rt_strlen(data), iv, data, data_encrypt); 37 | 38 | /* decrypt */ 39 | rt_memcpy(iv, TEST_TINY_AES_IV, rt_strlen(TEST_TINY_AES_IV)); 40 | iv[sizeof(iv) - 1] = '\0'; 41 | rt_memcpy(private_key, TEST_TINY_AES_KEY, rt_strlen(TEST_TINY_AES_KEY)); 42 | private_key[sizeof(private_key) - 1] = '\0'; 43 | 44 | rt_memset(data_decrypt, 0x0, sizeof(data_decrypt)); 45 | tiny_aes_setkey_dec(&ctx, (uint8_t *) private_key, 256); 46 | tiny_aes_crypt_cbc(&ctx, AES_DECRYPT, rt_strlen(data), iv, data_encrypt, data_decrypt); 47 | 48 | if(rt_memcmp(data, data_decrypt, rt_strlen(data)) == 0) 49 | { 50 | rt_kprintf("AES CBC mode passed!\n"); 51 | return RT_EOK; 52 | } 53 | else 54 | { 55 | rt_kprintf("AES CBC mode failed!"); 56 | return -RT_ERROR; 57 | } 58 | } 59 | #ifdef FINSH_USING_MSH 60 | MSH_CMD_EXPORT_ALIAS(test_tiny_aes, tiny_aes_sample, type tiny_aes_sample cmd to run); 61 | #endif /* FINSH_USING_MSH */ 62 | -------------------------------------------------------------------------------- /samples/md5_sample.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2021, RT-Thread Development Team 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | * 6 | * Change Logs: 7 | * Date Author Notes 8 | * 2021-07-26 WangQiang the first version 9 | */ 10 | 11 | #include 12 | 13 | #include 14 | 15 | 16 | static const uint8_t md5_test_buf[7][81] = 17 | { 18 | { "" }, 19 | { "a" }, 20 | { "abc" }, 21 | { "message digest" }, 22 | { "abcdefghijklmnopqrstuvwxyz" }, 23 | { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, 24 | { "12345678901234567890123456789012345678901234567890123456789012" 25 | "345678901234567890" } 26 | }; 27 | 28 | static const size_t md5_test_buflen[7] = 29 | { 30 | 0, 1, 3, 14, 26, 62, 80 31 | }; 32 | 33 | static const uint8_t md5_test_sum[7][16] = 34 | { 35 | { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, 36 | 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E }, 37 | { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8, 38 | 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 }, 39 | { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, 40 | 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 }, 41 | { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D, 42 | 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 }, 43 | { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00, 44 | 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B }, 45 | { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5, 46 | 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F }, 47 | { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55, 48 | 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A } 49 | }; 50 | 51 | static rt_err_t test_tiny_md5(void) 52 | { 53 | int i, ret = 0; 54 | uint8_t md5sum[16]; 55 | 56 | for (i = 0; i < 7; i++) 57 | { 58 | rt_kprintf(" MD5 test #%d: ", i + 1); 59 | 60 | tiny_md5(md5_test_buf[i], md5_test_buflen[i], md5sum); 61 | if (rt_memcmp(md5sum, md5_test_sum[i], 16) != 0) 62 | { 63 | ret = 1; 64 | goto fail; 65 | } 66 | rt_kprintf("passed\r\n"); 67 | } 68 | 69 | rt_kprintf("\r\n"); 70 | 71 | return (0); 72 | 73 | fail: 74 | rt_kprintf("failed\r\n"); 75 | 76 | return (ret); 77 | } 78 | #ifdef FINSH_USING_MSH 79 | MSH_CMD_EXPORT_ALIAS(test_tiny_md5, tiny_md5_sample, type tiny_md5_sample cmd to run); 80 | #endif /* FINSH_USING_MSH */ 81 | -------------------------------------------------------------------------------- /src/tiny_aes.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FIPS-197 compliant AES implementation 3 | * 4 | * Based on TropicSSL: Copyright (C) 2017 Shanghai Real-Thread Technology Co., Ltd 5 | * 6 | * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine 7 | * 8 | * Copyright (C) 2009 Paul Bakker 9 | * 10 | * All rights reserved. 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions 14 | * are met: 15 | * 16 | * * Redistributions of source code must retain the above copyright 17 | * notice, this list of conditions and the following disclaimer. 18 | * * Redistributions in binary form must reproduce the above copyright 19 | * notice, this list of conditions and the following disclaimer in the 20 | * documentation and/or other materials provided with the distribution. 21 | * * Neither the names of PolarSSL or XySSL nor the names of its contributors 22 | * may be used to endorse or promote products derived from this software 23 | * without specific prior written permission. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 28 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 31 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | */ 37 | /* 38 | * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. 39 | * 40 | * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf 41 | * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf 42 | */ 43 | 44 | #include "tinycrypt_config.h" 45 | 46 | #if defined(TINY_CRYPT_AES) 47 | 48 | #include "tinycrypt.h" 49 | #include 50 | 51 | /* 52 | * 32-bit integer manipulation macros (little endian) 53 | */ 54 | #ifndef GET_ULONG_LE 55 | #define GET_ULONG_LE(n,b,i) \ 56 | { \ 57 | (n) = ( (uint32_t) (b)[(i) ] ) \ 58 | | ( (uint32_t) (b)[(i) + 1] << 8 ) \ 59 | | ( (uint32_t) (b)[(i) + 2] << 16 ) \ 60 | | ( (uint32_t) (b)[(i) + 3] << 24 ); \ 61 | } 62 | #endif 63 | 64 | #ifndef PUT_ULONG_LE 65 | #define PUT_ULONG_LE(n,b,i) \ 66 | { \ 67 | (b)[(i) ] = (uint8_t) ( (n) ); \ 68 | (b)[(i) + 1] = (uint8_t) ( (n) >> 8 ); \ 69 | (b)[(i) + 2] = (uint8_t) ( (n) >> 16 ); \ 70 | (b)[(i) + 3] = (uint8_t) ( (n) >> 24 ); \ 71 | } 72 | #endif 73 | 74 | #if defined(TINY_CRYPT_AES_ROM_TABLES) 75 | /* 76 | * Forward S-box 77 | */ 78 | static const uint8_t FSb[256] = { 79 | 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 80 | 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 81 | 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 82 | 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 83 | 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 84 | 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 85 | 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 86 | 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 87 | 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 88 | 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 89 | 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 90 | 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 91 | 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 92 | 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 93 | 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 94 | 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 95 | 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 96 | 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 97 | 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 98 | 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 99 | 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 100 | 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 101 | 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 102 | 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 103 | 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 104 | 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 105 | 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 106 | 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 107 | 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 108 | 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 109 | 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 110 | 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 111 | }; 112 | 113 | /* 114 | * Forward tables 115 | */ 116 | #define FT \ 117 | \ 118 | V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \ 119 | V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \ 120 | V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \ 121 | V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \ 122 | V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \ 123 | V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \ 124 | V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \ 125 | V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \ 126 | V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \ 127 | V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \ 128 | V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \ 129 | V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \ 130 | V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \ 131 | V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \ 132 | V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \ 133 | V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \ 134 | V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \ 135 | V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \ 136 | V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \ 137 | V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \ 138 | V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \ 139 | V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \ 140 | V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \ 141 | V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \ 142 | V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \ 143 | V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \ 144 | V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \ 145 | V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \ 146 | V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \ 147 | V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \ 148 | V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \ 149 | V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \ 150 | V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \ 151 | V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \ 152 | V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \ 153 | V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \ 154 | V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \ 155 | V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \ 156 | V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \ 157 | V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \ 158 | V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \ 159 | V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \ 160 | V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \ 161 | V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \ 162 | V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \ 163 | V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \ 164 | V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \ 165 | V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \ 166 | V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \ 167 | V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \ 168 | V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \ 169 | V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \ 170 | V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \ 171 | V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \ 172 | V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \ 173 | V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \ 174 | V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \ 175 | V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \ 176 | V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \ 177 | V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \ 178 | V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \ 179 | V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \ 180 | V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \ 181 | V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C) 182 | 183 | #define V(a,b,c,d) 0x##a##b##c##d 184 | static const uint32_t FT0[256] = { FT }; 185 | 186 | #undef V 187 | 188 | #define V(a,b,c,d) 0x##b##c##d##a 189 | static const uint32_t FT1[256] = { FT }; 190 | 191 | #undef V 192 | 193 | #define V(a,b,c,d) 0x##c##d##a##b 194 | static const uint32_t FT2[256] = { FT }; 195 | 196 | #undef V 197 | 198 | #define V(a,b,c,d) 0x##d##a##b##c 199 | static const uint32_t FT3[256] = { FT }; 200 | 201 | #undef V 202 | 203 | #undef FT 204 | 205 | /* 206 | * Reverse S-box 207 | */ 208 | static const uint8_t RSb[256] = { 209 | 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 210 | 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, 211 | 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 212 | 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 213 | 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 214 | 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, 215 | 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 216 | 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, 217 | 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 218 | 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 219 | 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 220 | 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, 221 | 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 222 | 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, 223 | 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 224 | 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 225 | 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 226 | 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, 227 | 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 228 | 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, 229 | 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 230 | 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 231 | 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 232 | 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, 233 | 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 234 | 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, 235 | 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 236 | 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 237 | 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 238 | 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, 239 | 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 240 | 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D 241 | }; 242 | 243 | /* 244 | * Reverse tables 245 | */ 246 | #define RT \ 247 | \ 248 | V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \ 249 | V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \ 250 | V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \ 251 | V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \ 252 | V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \ 253 | V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \ 254 | V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \ 255 | V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \ 256 | V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \ 257 | V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \ 258 | V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \ 259 | V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \ 260 | V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \ 261 | V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \ 262 | V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \ 263 | V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \ 264 | V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \ 265 | V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \ 266 | V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \ 267 | V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \ 268 | V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \ 269 | V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \ 270 | V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \ 271 | V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \ 272 | V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \ 273 | V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \ 274 | V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \ 275 | V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \ 276 | V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \ 277 | V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \ 278 | V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \ 279 | V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \ 280 | V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \ 281 | V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \ 282 | V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \ 283 | V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \ 284 | V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \ 285 | V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \ 286 | V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \ 287 | V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \ 288 | V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \ 289 | V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \ 290 | V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \ 291 | V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \ 292 | V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \ 293 | V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \ 294 | V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \ 295 | V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \ 296 | V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \ 297 | V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \ 298 | V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \ 299 | V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \ 300 | V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \ 301 | V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \ 302 | V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \ 303 | V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \ 304 | V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \ 305 | V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \ 306 | V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \ 307 | V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \ 308 | V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \ 309 | V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \ 310 | V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \ 311 | V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0) 312 | 313 | #define V(a,b,c,d) 0x##a##b##c##d 314 | static const uint32_t RT0[256] = { RT }; 315 | 316 | #undef V 317 | 318 | #define V(a,b,c,d) 0x##b##c##d##a 319 | static const uint32_t RT1[256] = { RT }; 320 | 321 | #undef V 322 | 323 | #define V(a,b,c,d) 0x##c##d##a##b 324 | static const uint32_t RT2[256] = { RT }; 325 | 326 | #undef V 327 | 328 | #define V(a,b,c,d) 0x##d##a##b##c 329 | static const uint32_t RT3[256] = { RT }; 330 | 331 | #undef V 332 | 333 | #undef RT 334 | 335 | /* 336 | * Round constants 337 | */ 338 | static const uint32_t RCON[10] = { 339 | 0x00000001, 0x00000002, 0x00000004, 0x00000008, 340 | 0x00000010, 0x00000020, 0x00000040, 0x00000080, 341 | 0x0000001B, 0x00000036 342 | }; 343 | 344 | #else 345 | 346 | /* 347 | * Forward S-box & tables 348 | */ 349 | static uint8_t FSb[256]; 350 | static uint32_t FT0[256]; 351 | static uint32_t FT1[256]; 352 | static uint32_t FT2[256]; 353 | static uint32_t FT3[256]; 354 | 355 | /* 356 | * Reverse S-box & tables 357 | */ 358 | static uint8_t RSb[256]; 359 | static uint32_t RT0[256]; 360 | static uint32_t RT1[256]; 361 | static uint32_t RT2[256]; 362 | static uint32_t RT3[256]; 363 | 364 | /* 365 | * Round constants 366 | */ 367 | static uint32_t RCON[10]; 368 | 369 | /* 370 | * Tables generation code 371 | */ 372 | #define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 ) 373 | #define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) ) 374 | #define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 ) 375 | 376 | static int aes_init_done = 0; 377 | 378 | static void aes_gen_tables(void) 379 | { 380 | int i, x, y, z; 381 | int pow[256]; 382 | int log[256]; 383 | 384 | /* 385 | * compute pow and log tables over GF(2^8) 386 | */ 387 | for (i = 0, x = 1; i < 256; i++) { 388 | pow[i] = x; 389 | log[x] = i; 390 | x = (x ^ XTIME(x)) & 0xFF; 391 | } 392 | 393 | /* 394 | * calculate the round constants 395 | */ 396 | for (i = 0, x = 1; i < 10; i++) { 397 | RCON[i] = (uint32_t)x; 398 | x = XTIME(x) & 0xFF; 399 | } 400 | 401 | /* 402 | * generate the forward and reverse S-boxes 403 | */ 404 | FSb[0x00] = 0x63; 405 | RSb[0x63] = 0x00; 406 | 407 | for (i = 1; i < 256; i++) { 408 | x = pow[255 - log[i]]; 409 | 410 | y = x; 411 | y = ((y << 1) | (y >> 7)) & 0xFF; 412 | x ^= y; 413 | y = ((y << 1) | (y >> 7)) & 0xFF; 414 | x ^= y; 415 | y = ((y << 1) | (y >> 7)) & 0xFF; 416 | x ^= y; 417 | y = ((y << 1) | (y >> 7)) & 0xFF; 418 | x ^= y ^ 0x63; 419 | 420 | FSb[i] = (uint8_t)x; 421 | RSb[x] = (uint8_t)i; 422 | } 423 | 424 | /* 425 | * generate the forward and reverse tables 426 | */ 427 | for (i = 0; i < 256; i++) { 428 | x = FSb[i]; 429 | y = XTIME(x) & 0xFF; 430 | z = (y ^ x) & 0xFF; 431 | 432 | FT0[i] = ((uint32_t)y) ^ 433 | ((uint32_t)x << 8) ^ 434 | ((uint32_t)x << 16) ^ ((uint32_t)z << 24); 435 | 436 | FT1[i] = ROTL8(FT0[i]); 437 | FT2[i] = ROTL8(FT1[i]); 438 | FT3[i] = ROTL8(FT2[i]); 439 | 440 | x = RSb[i]; 441 | 442 | RT0[i] = ((uint32_t)MUL(0x0E, x)) ^ 443 | ((uint32_t)MUL(0x09, x) << 8) ^ 444 | ((uint32_t)MUL(0x0D, x) << 16) ^ 445 | ((uint32_t)MUL(0x0B, x) << 24); 446 | 447 | RT1[i] = ROTL8(RT0[i]); 448 | RT2[i] = ROTL8(RT1[i]); 449 | RT3[i] = ROTL8(RT2[i]); 450 | } 451 | } 452 | 453 | #endif 454 | 455 | /* 456 | * AES key schedule (encryption) 457 | */ 458 | void tiny_aes_setkey_enc(tiny_aes_context * ctx, uint8_t *key, int keysize) 459 | { 460 | int i; 461 | uint32_t *RK; 462 | 463 | #if !defined(TINY_CRYPT_AES_ROM_TABLES) 464 | if (aes_init_done == 0) { 465 | aes_gen_tables(); 466 | aes_init_done = 1; 467 | } 468 | #endif 469 | 470 | switch (keysize) { 471 | case 128: 472 | ctx->nr = 10; 473 | break; 474 | case 192: 475 | ctx->nr = 12; 476 | break; 477 | case 256: 478 | ctx->nr = 14; 479 | break; 480 | default: 481 | return; 482 | } 483 | 484 | ctx->rk = RK = ctx->buf; 485 | 486 | for (i = 0; i < (keysize >> 5); i++) { 487 | GET_ULONG_LE(RK[i], key, i << 2); 488 | } 489 | 490 | switch (ctx->nr) { 491 | case 10: 492 | 493 | for (i = 0; i < 10; i++, RK += 4) { 494 | RK[4] = RK[0] ^ RCON[i] ^ 495 | ((uint32_t)FSb[(RK[3] >> 8) & 0xFF]) ^ 496 | ((uint32_t)FSb[(RK[3] >> 16) & 0xFF] << 8) ^ 497 | ((uint32_t)FSb[(RK[3] >> 24) & 0xFF] << 16) ^ 498 | ((uint32_t)FSb[(RK[3]) & 0xFF] << 24); 499 | 500 | RK[5] = RK[1] ^ RK[4]; 501 | RK[6] = RK[2] ^ RK[5]; 502 | RK[7] = RK[3] ^ RK[6]; 503 | } 504 | break; 505 | 506 | case 12: 507 | 508 | for (i = 0; i < 8; i++, RK += 6) { 509 | RK[6] = RK[0] ^ RCON[i] ^ 510 | ((uint32_t)FSb[(RK[5] >> 8) & 0xFF]) ^ 511 | ((uint32_t)FSb[(RK[5] >> 16) & 0xFF] << 8) ^ 512 | ((uint32_t)FSb[(RK[5] >> 24) & 0xFF] << 16) ^ 513 | ((uint32_t)FSb[(RK[5]) & 0xFF] << 24); 514 | 515 | RK[7] = RK[1] ^ RK[6]; 516 | RK[8] = RK[2] ^ RK[7]; 517 | RK[9] = RK[3] ^ RK[8]; 518 | RK[10] = RK[4] ^ RK[9]; 519 | RK[11] = RK[5] ^ RK[10]; 520 | } 521 | break; 522 | 523 | case 14: 524 | 525 | for (i = 0; i < 7; i++, RK += 8) { 526 | RK[8] = RK[0] ^ RCON[i] ^ 527 | ((uint32_t)FSb[(RK[7] >> 8) & 0xFF]) ^ 528 | ((uint32_t)FSb[(RK[7] >> 16) & 0xFF] << 8) ^ 529 | ((uint32_t)FSb[(RK[7] >> 24) & 0xFF] << 16) ^ 530 | ((uint32_t)FSb[(RK[7]) & 0xFF] << 24); 531 | 532 | RK[9] = RK[1] ^ RK[8]; 533 | RK[10] = RK[2] ^ RK[9]; 534 | RK[11] = RK[3] ^ RK[10]; 535 | 536 | RK[12] = RK[4] ^ 537 | ((uint32_t)FSb[(RK[11]) & 0xFF]) ^ 538 | ((uint32_t)FSb[(RK[11] >> 8) & 0xFF] << 8) ^ 539 | ((uint32_t)FSb[(RK[11] >> 16) & 0xFF] << 16) ^ 540 | ((uint32_t)FSb[(RK[11] >> 24) & 0xFF] << 24); 541 | 542 | RK[13] = RK[5] ^ RK[12]; 543 | RK[14] = RK[6] ^ RK[13]; 544 | RK[15] = RK[7] ^ RK[14]; 545 | } 546 | break; 547 | 548 | default: 549 | 550 | break; 551 | } 552 | } 553 | 554 | /* 555 | * AES key schedule (decryption) 556 | */ 557 | void tiny_aes_setkey_dec(tiny_aes_context * ctx, uint8_t *key, int keysize) 558 | { 559 | int i, j; 560 | tiny_aes_context cty; 561 | uint32_t *RK; 562 | uint32_t *SK; 563 | 564 | switch (keysize) { 565 | case 128: 566 | ctx->nr = 10; 567 | break; 568 | case 192: 569 | ctx->nr = 12; 570 | break; 571 | case 256: 572 | ctx->nr = 14; 573 | break; 574 | default: 575 | return; 576 | } 577 | 578 | ctx->rk = RK = ctx->buf; 579 | 580 | tiny_aes_setkey_enc(&cty, key, keysize); 581 | SK = cty.rk + cty.nr * 4; 582 | 583 | *RK++ = *SK++; 584 | *RK++ = *SK++; 585 | *RK++ = *SK++; 586 | *RK++ = *SK++; 587 | 588 | for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) { 589 | for (j = 0; j < 4; j++, SK++) { 590 | *RK++ = RT0[FSb[(*SK) & 0xFF]] ^ 591 | RT1[FSb[(*SK >> 8) & 0xFF]] ^ 592 | RT2[FSb[(*SK >> 16) & 0xFF]] ^ 593 | RT3[FSb[(*SK >> 24) & 0xFF]]; 594 | } 595 | } 596 | 597 | *RK++ = *SK++; 598 | *RK++ = *SK++; 599 | *RK++ = *SK++; 600 | *RK++ = *SK++; 601 | 602 | memset(&cty, 0, sizeof(tiny_aes_context)); 603 | } 604 | 605 | #define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ 606 | { \ 607 | X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \ 608 | FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ 609 | FT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ 610 | FT3[ ( Y3 >> 24 ) & 0xFF ]; \ 611 | \ 612 | X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \ 613 | FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ 614 | FT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ 615 | FT3[ ( Y0 >> 24 ) & 0xFF ]; \ 616 | \ 617 | X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \ 618 | FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ 619 | FT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ 620 | FT3[ ( Y1 >> 24 ) & 0xFF ]; \ 621 | \ 622 | X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \ 623 | FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ 624 | FT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ 625 | FT3[ ( Y2 >> 24 ) & 0xFF ]; \ 626 | } 627 | 628 | #define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ 629 | { \ 630 | X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^ \ 631 | RT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ 632 | RT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ 633 | RT3[ ( Y1 >> 24 ) & 0xFF ]; \ 634 | \ 635 | X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^ \ 636 | RT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ 637 | RT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ 638 | RT3[ ( Y2 >> 24 ) & 0xFF ]; \ 639 | \ 640 | X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^ \ 641 | RT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ 642 | RT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ 643 | RT3[ ( Y3 >> 24 ) & 0xFF ]; \ 644 | \ 645 | X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^ \ 646 | RT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ 647 | RT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ 648 | RT3[ ( Y0 >> 24 ) & 0xFF ]; \ 649 | } 650 | 651 | /* 652 | * AES-ECB block encryption/decryption 653 | */ 654 | void tiny_aes_crypt_ecb(tiny_aes_context * ctx, 655 | int mode, uint8_t input[16], uint8_t output[16]) 656 | { 657 | int i; 658 | uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; 659 | 660 | RK = ctx->rk; 661 | 662 | GET_ULONG_LE(X0, input, 0); 663 | X0 ^= *RK++; 664 | GET_ULONG_LE(X1, input, 4); 665 | X1 ^= *RK++; 666 | GET_ULONG_LE(X2, input, 8); 667 | X2 ^= *RK++; 668 | GET_ULONG_LE(X3, input, 12); 669 | X3 ^= *RK++; 670 | 671 | if (mode == AES_DECRYPT) { 672 | for (i = (ctx->nr >> 1) - 1; i > 0; i--) { 673 | AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); 674 | AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); 675 | } 676 | 677 | AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); 678 | 679 | X0 = *RK++ ^ 680 | ((uint32_t)RSb[(Y0) & 0xFF]) ^ 681 | ((uint32_t)RSb[(Y3 >> 8) & 0xFF] << 8) ^ 682 | ((uint32_t)RSb[(Y2 >> 16) & 0xFF] << 16) ^ 683 | ((uint32_t)RSb[(Y1 >> 24) & 0xFF] << 24); 684 | 685 | X1 = *RK++ ^ 686 | ((uint32_t)RSb[(Y1) & 0xFF]) ^ 687 | ((uint32_t)RSb[(Y0 >> 8) & 0xFF] << 8) ^ 688 | ((uint32_t)RSb[(Y3 >> 16) & 0xFF] << 16) ^ 689 | ((uint32_t)RSb[(Y2 >> 24) & 0xFF] << 24); 690 | 691 | X2 = *RK++ ^ 692 | ((uint32_t)RSb[(Y2) & 0xFF]) ^ 693 | ((uint32_t)RSb[(Y1 >> 8) & 0xFF] << 8) ^ 694 | ((uint32_t)RSb[(Y0 >> 16) & 0xFF] << 16) ^ 695 | ((uint32_t)RSb[(Y3 >> 24) & 0xFF] << 24); 696 | 697 | X3 = *RK++ ^ 698 | ((uint32_t)RSb[(Y3) & 0xFF]) ^ 699 | ((uint32_t)RSb[(Y2 >> 8) & 0xFF] << 8) ^ 700 | ((uint32_t)RSb[(Y1 >> 16) & 0xFF] << 16) ^ 701 | ((uint32_t)RSb[(Y0 >> 24) & 0xFF] << 24); 702 | } else { /* AES_ENCRYPT */ 703 | for (i = (ctx->nr >> 1) - 1; i > 0; i--) { 704 | AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); 705 | AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); 706 | } 707 | 708 | AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); 709 | 710 | X0 = *RK++ ^ 711 | ((uint32_t)FSb[(Y0) & 0xFF]) ^ 712 | ((uint32_t)FSb[(Y1 >> 8) & 0xFF] << 8) ^ 713 | ((uint32_t)FSb[(Y2 >> 16) & 0xFF] << 16) ^ 714 | ((uint32_t)FSb[(Y3 >> 24) & 0xFF] << 24); 715 | 716 | X1 = *RK++ ^ 717 | ((uint32_t)FSb[(Y1) & 0xFF]) ^ 718 | ((uint32_t)FSb[(Y2 >> 8) & 0xFF] << 8) ^ 719 | ((uint32_t)FSb[(Y3 >> 16) & 0xFF] << 16) ^ 720 | ((uint32_t)FSb[(Y0 >> 24) & 0xFF] << 24); 721 | 722 | X2 = *RK++ ^ 723 | ((uint32_t)FSb[(Y2) & 0xFF]) ^ 724 | ((uint32_t)FSb[(Y3 >> 8) & 0xFF] << 8) ^ 725 | ((uint32_t)FSb[(Y0 >> 16) & 0xFF] << 16) ^ 726 | ((uint32_t)FSb[(Y1 >> 24) & 0xFF] << 24); 727 | 728 | X3 = *RK++ ^ 729 | ((uint32_t)FSb[(Y3) & 0xFF]) ^ 730 | ((uint32_t)FSb[(Y0 >> 8) & 0xFF] << 8) ^ 731 | ((uint32_t)FSb[(Y1 >> 16) & 0xFF] << 16) ^ 732 | ((uint32_t)FSb[(Y2 >> 24) & 0xFF] << 24); 733 | } 734 | 735 | PUT_ULONG_LE(X0, output, 0); 736 | PUT_ULONG_LE(X1, output, 4); 737 | PUT_ULONG_LE(X2, output, 8); 738 | PUT_ULONG_LE(X3, output, 12); 739 | } 740 | 741 | /* 742 | * AES-CBC buffer encryption/decryption 743 | */ 744 | void tiny_aes_crypt_cbc(tiny_aes_context * ctx, 745 | int mode, 746 | int length, 747 | uint8_t iv[16], 748 | uint8_t *input, uint8_t *output) 749 | { 750 | int i; 751 | uint8_t temp[16]; 752 | 753 | if (mode == AES_DECRYPT) { 754 | while (length > 0) { 755 | memcpy(temp, input, 16); 756 | tiny_aes_crypt_ecb(ctx, mode, input, output); 757 | 758 | for (i = 0; i < 16; i++) 759 | output[i] = (uint8_t)(output[i] ^ iv[i]); 760 | 761 | memcpy(iv, temp, 16); 762 | 763 | input += 16; 764 | output += 16; 765 | length -= 16; 766 | } 767 | } else { 768 | while (length > 0) { 769 | for (i = 0; i < 16; i++) 770 | output[i] = (uint8_t)(input[i] ^ iv[i]); 771 | 772 | tiny_aes_crypt_ecb(ctx, mode, output, output); 773 | memcpy(iv, output, 16); 774 | 775 | input += 16; 776 | output += 16; 777 | length -= 16; 778 | } 779 | } 780 | } 781 | 782 | /* 783 | * AES-CFB128 buffer encryption/decryption 784 | */ 785 | void tiny_aes_crypt_cfb128(tiny_aes_context * ctx, 786 | int mode, 787 | int length, 788 | int *iv_off, 789 | uint8_t iv[16], 790 | uint8_t *input, uint8_t *output) 791 | { 792 | int c, n = *iv_off; 793 | 794 | if (mode == AES_DECRYPT) { 795 | while (length--) { 796 | if (n == 0) 797 | tiny_aes_crypt_ecb(ctx, AES_ENCRYPT, iv, iv); 798 | 799 | c = *input++; 800 | *output++ = (uint8_t)(c ^ iv[n]); 801 | iv[n] = (uint8_t)c; 802 | 803 | n = (n + 1) & 0x0F; 804 | } 805 | } else { 806 | while (length--) { 807 | if (n == 0) 808 | tiny_aes_crypt_ecb(ctx, AES_ENCRYPT, iv, iv); 809 | 810 | iv[n] = *output++ = (uint8_t)(iv[n] ^ *input++); 811 | 812 | n = (n + 1) & 0x0F; 813 | } 814 | } 815 | 816 | *iv_off = n; 817 | } 818 | 819 | #endif 820 | -------------------------------------------------------------------------------- /src/tiny_base64.c: -------------------------------------------------------------------------------- 1 | /* 2 | * RFC 1521 base64 encoding/decoding 3 | * 4 | * Based on TropicSSL: Copyright (C) 2017 Shanghai Real-Thread Technology Co., Ltd 5 | * 6 | * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine 7 | * 8 | * Copyright (C) 2009 Paul Bakker 9 | * 10 | * All rights reserved. 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions 14 | * are met: 15 | * 16 | * * Redistributions of source code must retain the above copyright 17 | * notice, this list of conditions and the following disclaimer. 18 | * * Redistributions in binary form must reproduce the above copyright 19 | * notice, this list of conditions and the following disclaimer in the 20 | * documentation and/or other materials provided with the distribution. 21 | * * Neither the names of PolarSSL or XySSL nor the names of its contributors 22 | * may be used to endorse or promote products derived from this software 23 | * without specific prior written permission. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 28 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 31 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | */ 37 | 38 | #include "tinycrypt_config.h" 39 | 40 | #if defined(TINY_CRYPT_BASE64) 41 | 42 | #include "tinycrypt.h" 43 | 44 | static const uint8_t base64_enc_map[64] = { 45 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 46 | 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 47 | 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 48 | 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 49 | 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 50 | 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', 51 | '8', '9', '+', '/' 52 | }; 53 | 54 | static const uint8_t base64_dec_map[128] = { 55 | 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 56 | 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 57 | 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 58 | 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 59 | 127, 127, 127, 62, 127, 127, 127, 63, 52, 53, 60 | 54, 55, 56, 57, 58, 59, 60, 61, 127, 127, 61 | 127, 64, 127, 127, 127, 0, 1, 2, 3, 4, 62 | 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 63 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 64 | 25, 127, 127, 127, 127, 127, 127, 26, 27, 28, 65 | 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 66 | 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 67 | 49, 50, 51, 127, 127, 127, 127, 127 68 | }; 69 | 70 | /* 71 | * Encode a buffer into base64 format 72 | */ 73 | int tiny_base64_encode(uint8_t *dst, int *dlen, uint8_t *src, int slen) 74 | { 75 | int i, n; 76 | int C1, C2, C3; 77 | uint8_t *p; 78 | 79 | if (slen == 0) 80 | return (0); 81 | 82 | n = (slen << 3) / 6; 83 | 84 | switch ((slen << 3) - (n * 6)) { 85 | case 2: 86 | n += 3; 87 | break; 88 | case 4: 89 | n += 2; 90 | break; 91 | default: 92 | break; 93 | } 94 | 95 | if (*dlen < n + 1) { 96 | *dlen = n + 1; 97 | return (ERR_BASE64_BUFFER_TOO_SMALL); 98 | } 99 | 100 | n = (slen / 3) * 3; 101 | 102 | for (i = 0, p = dst; i < n; i += 3) { 103 | C1 = *src++; 104 | C2 = *src++; 105 | C3 = *src++; 106 | 107 | *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; 108 | *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; 109 | *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F]; 110 | *p++ = base64_enc_map[C3 & 0x3F]; 111 | } 112 | 113 | if (i < slen) { 114 | C1 = *src++; 115 | C2 = ((i + 1) < slen) ? *src++ : 0; 116 | 117 | *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; 118 | *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; 119 | 120 | if ((i + 1) < slen) 121 | *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F]; 122 | else 123 | *p++ = '='; 124 | 125 | *p++ = '='; 126 | } 127 | 128 | *dlen = p - dst; 129 | *p = 0; 130 | 131 | return (0); 132 | } 133 | 134 | /* 135 | * Decode a base64-formatted buffer 136 | */ 137 | int tiny_base64_decode(uint8_t *dst, int *dlen, uint8_t *src, int slen) 138 | { 139 | int i, j, n; 140 | uint32_t x; 141 | uint8_t *p; 142 | 143 | for (i = j = n = 0; i < slen; i++) { 144 | if ((slen - i) >= 2 && src[i] == '\r' && src[i + 1] == '\n') 145 | continue; 146 | 147 | if (src[i] == '\n') 148 | continue; 149 | 150 | if (src[i] == '=' && ++j > 2) 151 | return (ERR_BASE64_INVALID_CHARACTER); 152 | 153 | if (src[i] > 127 || base64_dec_map[src[i]] == 127) 154 | return (ERR_BASE64_INVALID_CHARACTER); 155 | 156 | if (base64_dec_map[src[i]] < 64 && j != 0) 157 | return (ERR_BASE64_INVALID_CHARACTER); 158 | 159 | n++; 160 | } 161 | 162 | if (n == 0) 163 | return (0); 164 | 165 | n = ((n * 6) + 7) >> 3; 166 | 167 | if (*dlen < n) { 168 | *dlen = n; 169 | return (ERR_BASE64_BUFFER_TOO_SMALL); 170 | } 171 | 172 | for (j = 3, n = x = 0, p = dst; i > 0; i--, src++) { 173 | if (*src == '\r' || *src == '\n') 174 | continue; 175 | 176 | j -= (base64_dec_map[*src] == 64); 177 | x = (x << 6) | (base64_dec_map[*src] & 0x3F); 178 | 179 | if (++n == 4) { 180 | n = 0; 181 | if (j > 0) 182 | *p++ = (uint8_t)(x >> 16); 183 | if (j > 1) 184 | *p++ = (uint8_t)(x >> 8); 185 | if (j > 2) 186 | *p++ = (uint8_t)(x); 187 | } 188 | } 189 | 190 | *dlen = p - dst; 191 | 192 | return (0); 193 | } 194 | 195 | #endif 196 | -------------------------------------------------------------------------------- /src/tiny_md5.c: -------------------------------------------------------------------------------- 1 | /* 2 | * RFC 1321 compliant MD5 implementation 3 | * 4 | * Based on TropicSSL: Copyright (C) 2017 Shanghai Real-Thread Technology Co., Ltd 5 | * 6 | * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine 7 | * 8 | * Copyright (C) 2009 Paul Bakker 9 | * 10 | * All rights reserved. 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions 14 | * are met: 15 | * 16 | * * Redistributions of source code must retain the above copyright 17 | * notice, this list of conditions and the following disclaimer. 18 | * * Redistributions in binary form must reproduce the above copyright 19 | * notice, this list of conditions and the following disclaimer in the 20 | * documentation and/or other materials provided with the distribution. 21 | * * Neither the names of PolarSSL or XySSL nor the names of its contributors 22 | * may be used to endorse or promote products derived from this software 23 | * without specific prior written permission. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 28 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 31 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | */ 37 | /* 38 | * The MD5 algorithm was designed by Ron Rivest in 1991. 39 | * 40 | * http://www.ietf.org/rfc/rfc1321.txt 41 | */ 42 | 43 | #include "tinycrypt_config.h" 44 | 45 | #if defined(TINY_CRYPT_MD5) 46 | 47 | #include "tinycrypt.h" 48 | 49 | #include 50 | #include 51 | 52 | /* 53 | * 32-bit integer manipulation macros (little endian) 54 | */ 55 | #ifndef GET_ULONG_LE 56 | #define GET_ULONG_LE(n,b,i) \ 57 | { \ 58 | (n) = ( (uint32_t) (b)[(i) ] ) \ 59 | | ( (uint32_t) (b)[(i) + 1] << 8 ) \ 60 | | ( (uint32_t) (b)[(i) + 2] << 16 ) \ 61 | | ( (uint32_t) (b)[(i) + 3] << 24 ); \ 62 | } 63 | #endif 64 | 65 | #ifndef PUT_ULONG_LE 66 | #define PUT_ULONG_LE(n,b,i) \ 67 | { \ 68 | (b)[(i) ] = (uint8_t) ( (n) ); \ 69 | (b)[(i) + 1] = (uint8_t) ( (n) >> 8 ); \ 70 | (b)[(i) + 2] = (uint8_t) ( (n) >> 16 ); \ 71 | (b)[(i) + 3] = (uint8_t) ( (n) >> 24 ); \ 72 | } 73 | #endif 74 | 75 | /* 76 | * MD5 context setup 77 | */ 78 | void tiny_md5_starts(tiny_md5_context * ctx) 79 | { 80 | ctx->total[0] = 0; 81 | ctx->total[1] = 0; 82 | 83 | ctx->state[0] = 0x67452301; 84 | ctx->state[1] = 0xEFCDAB89; 85 | ctx->state[2] = 0x98BADCFE; 86 | ctx->state[3] = 0x10325476; 87 | } 88 | 89 | static void md5_process(tiny_md5_context * ctx, uint8_t data[64]) 90 | { 91 | uint32_t X[16], A, B, C, D; 92 | 93 | GET_ULONG_LE(X[0], data, 0); 94 | GET_ULONG_LE(X[1], data, 4); 95 | GET_ULONG_LE(X[2], data, 8); 96 | GET_ULONG_LE(X[3], data, 12); 97 | GET_ULONG_LE(X[4], data, 16); 98 | GET_ULONG_LE(X[5], data, 20); 99 | GET_ULONG_LE(X[6], data, 24); 100 | GET_ULONG_LE(X[7], data, 28); 101 | GET_ULONG_LE(X[8], data, 32); 102 | GET_ULONG_LE(X[9], data, 36); 103 | GET_ULONG_LE(X[10], data, 40); 104 | GET_ULONG_LE(X[11], data, 44); 105 | GET_ULONG_LE(X[12], data, 48); 106 | GET_ULONG_LE(X[13], data, 52); 107 | GET_ULONG_LE(X[14], data, 56); 108 | GET_ULONG_LE(X[15], data, 60); 109 | 110 | #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) 111 | 112 | #define P(a,b,c,d,k,s,t) \ 113 | { \ 114 | a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ 115 | } 116 | 117 | A = ctx->state[0]; 118 | B = ctx->state[1]; 119 | C = ctx->state[2]; 120 | D = ctx->state[3]; 121 | 122 | #define F(x,y,z) (z ^ (x & (y ^ z))) 123 | 124 | P(A, B, C, D, 0, 7, 0xD76AA478); 125 | P(D, A, B, C, 1, 12, 0xE8C7B756); 126 | P(C, D, A, B, 2, 17, 0x242070DB); 127 | P(B, C, D, A, 3, 22, 0xC1BDCEEE); 128 | P(A, B, C, D, 4, 7, 0xF57C0FAF); 129 | P(D, A, B, C, 5, 12, 0x4787C62A); 130 | P(C, D, A, B, 6, 17, 0xA8304613); 131 | P(B, C, D, A, 7, 22, 0xFD469501); 132 | P(A, B, C, D, 8, 7, 0x698098D8); 133 | P(D, A, B, C, 9, 12, 0x8B44F7AF); 134 | P(C, D, A, B, 10, 17, 0xFFFF5BB1); 135 | P(B, C, D, A, 11, 22, 0x895CD7BE); 136 | P(A, B, C, D, 12, 7, 0x6B901122); 137 | P(D, A, B, C, 13, 12, 0xFD987193); 138 | P(C, D, A, B, 14, 17, 0xA679438E); 139 | P(B, C, D, A, 15, 22, 0x49B40821); 140 | 141 | #undef F 142 | 143 | #define F(x,y,z) (y ^ (z & (x ^ y))) 144 | 145 | P(A, B, C, D, 1, 5, 0xF61E2562); 146 | P(D, A, B, C, 6, 9, 0xC040B340); 147 | P(C, D, A, B, 11, 14, 0x265E5A51); 148 | P(B, C, D, A, 0, 20, 0xE9B6C7AA); 149 | P(A, B, C, D, 5, 5, 0xD62F105D); 150 | P(D, A, B, C, 10, 9, 0x02441453); 151 | P(C, D, A, B, 15, 14, 0xD8A1E681); 152 | P(B, C, D, A, 4, 20, 0xE7D3FBC8); 153 | P(A, B, C, D, 9, 5, 0x21E1CDE6); 154 | P(D, A, B, C, 14, 9, 0xC33707D6); 155 | P(C, D, A, B, 3, 14, 0xF4D50D87); 156 | P(B, C, D, A, 8, 20, 0x455A14ED); 157 | P(A, B, C, D, 13, 5, 0xA9E3E905); 158 | P(D, A, B, C, 2, 9, 0xFCEFA3F8); 159 | P(C, D, A, B, 7, 14, 0x676F02D9); 160 | P(B, C, D, A, 12, 20, 0x8D2A4C8A); 161 | 162 | #undef F 163 | 164 | #define F(x,y,z) (x ^ y ^ z) 165 | 166 | P(A, B, C, D, 5, 4, 0xFFFA3942); 167 | P(D, A, B, C, 8, 11, 0x8771F681); 168 | P(C, D, A, B, 11, 16, 0x6D9D6122); 169 | P(B, C, D, A, 14, 23, 0xFDE5380C); 170 | P(A, B, C, D, 1, 4, 0xA4BEEA44); 171 | P(D, A, B, C, 4, 11, 0x4BDECFA9); 172 | P(C, D, A, B, 7, 16, 0xF6BB4B60); 173 | P(B, C, D, A, 10, 23, 0xBEBFBC70); 174 | P(A, B, C, D, 13, 4, 0x289B7EC6); 175 | P(D, A, B, C, 0, 11, 0xEAA127FA); 176 | P(C, D, A, B, 3, 16, 0xD4EF3085); 177 | P(B, C, D, A, 6, 23, 0x04881D05); 178 | P(A, B, C, D, 9, 4, 0xD9D4D039); 179 | P(D, A, B, C, 12, 11, 0xE6DB99E5); 180 | P(C, D, A, B, 15, 16, 0x1FA27CF8); 181 | P(B, C, D, A, 2, 23, 0xC4AC5665); 182 | 183 | #undef F 184 | 185 | #define F(x,y,z) (y ^ (x | ~z)) 186 | 187 | P(A, B, C, D, 0, 6, 0xF4292244); 188 | P(D, A, B, C, 7, 10, 0x432AFF97); 189 | P(C, D, A, B, 14, 15, 0xAB9423A7); 190 | P(B, C, D, A, 5, 21, 0xFC93A039); 191 | P(A, B, C, D, 12, 6, 0x655B59C3); 192 | P(D, A, B, C, 3, 10, 0x8F0CCC92); 193 | P(C, D, A, B, 10, 15, 0xFFEFF47D); 194 | P(B, C, D, A, 1, 21, 0x85845DD1); 195 | P(A, B, C, D, 8, 6, 0x6FA87E4F); 196 | P(D, A, B, C, 15, 10, 0xFE2CE6E0); 197 | P(C, D, A, B, 6, 15, 0xA3014314); 198 | P(B, C, D, A, 13, 21, 0x4E0811A1); 199 | P(A, B, C, D, 4, 6, 0xF7537E82); 200 | P(D, A, B, C, 11, 10, 0xBD3AF235); 201 | P(C, D, A, B, 2, 15, 0x2AD7D2BB); 202 | P(B, C, D, A, 9, 21, 0xEB86D391); 203 | 204 | #undef F 205 | 206 | ctx->state[0] += A; 207 | ctx->state[1] += B; 208 | ctx->state[2] += C; 209 | ctx->state[3] += D; 210 | } 211 | 212 | /* 213 | * MD5 process buffer 214 | */ 215 | void tiny_md5_update(tiny_md5_context * ctx, uint8_t *input, int ilen) 216 | { 217 | int fill; 218 | uint32_t left; 219 | 220 | if (ilen <= 0) 221 | return; 222 | 223 | left = ctx->total[0] & 0x3F; 224 | fill = 64 - left; 225 | 226 | ctx->total[0] += ilen; 227 | ctx->total[0] &= 0xFFFFFFFF; 228 | 229 | if (ctx->total[0] < (uint32_t)ilen) 230 | ctx->total[1]++; 231 | 232 | if (left && ilen >= fill) { 233 | memcpy((void *)(ctx->buffer + left), (void *)input, fill); 234 | md5_process(ctx, ctx->buffer); 235 | input += fill; 236 | ilen -= fill; 237 | left = 0; 238 | } 239 | 240 | while (ilen >= 64) { 241 | md5_process(ctx, input); 242 | input += 64; 243 | ilen -= 64; 244 | } 245 | 246 | if (ilen > 0) { 247 | memcpy((void *)(ctx->buffer + left), (void *)input, ilen); 248 | } 249 | } 250 | 251 | static const uint8_t md5_padding[64] = { 252 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 253 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 256 | }; 257 | 258 | /* 259 | * MD5 final digest 260 | */ 261 | void tiny_md5_finish(tiny_md5_context * ctx, uint8_t output[16]) 262 | { 263 | uint32_t last, padn; 264 | uint32_t high, low; 265 | uint8_t msglen[8]; 266 | 267 | high = (ctx->total[0] >> 29) 268 | | (ctx->total[1] << 3); 269 | low = (ctx->total[0] << 3); 270 | 271 | PUT_ULONG_LE(low, msglen, 0); 272 | PUT_ULONG_LE(high, msglen, 4); 273 | 274 | last = ctx->total[0] & 0x3F; 275 | padn = (last < 56) ? (56 - last) : (120 - last); 276 | 277 | tiny_md5_update(ctx, (uint8_t *)md5_padding, padn); 278 | tiny_md5_update(ctx, msglen, 8); 279 | 280 | PUT_ULONG_LE(ctx->state[0], output, 0); 281 | PUT_ULONG_LE(ctx->state[1], output, 4); 282 | PUT_ULONG_LE(ctx->state[2], output, 8); 283 | PUT_ULONG_LE(ctx->state[3], output, 12); 284 | } 285 | 286 | /* 287 | * output = MD5( input buffer ) 288 | */ 289 | void tiny_md5(uint8_t *input, int ilen, uint8_t output[16]) 290 | { 291 | tiny_md5_context ctx; 292 | 293 | tiny_md5_starts(&ctx); 294 | tiny_md5_update(&ctx, input, ilen); 295 | tiny_md5_finish(&ctx, output); 296 | 297 | memset(&ctx, 0, sizeof(tiny_md5_context)); 298 | } 299 | 300 | /* 301 | * MD5 HMAC context setup 302 | */ 303 | void tiny_md5_hmac_starts(tiny_md5_context * ctx, uint8_t *key, int keylen) 304 | { 305 | int i; 306 | uint8_t sum[16]; 307 | 308 | if (keylen > 64) { 309 | tiny_md5(key, keylen, sum); 310 | keylen = 16; 311 | key = sum; 312 | } 313 | 314 | memset(ctx->ipad, 0x36, 64); 315 | memset(ctx->opad, 0x5C, 64); 316 | 317 | for (i = 0; i < keylen; i++) { 318 | ctx->ipad[i] = (uint8_t)(ctx->ipad[i] ^ key[i]); 319 | ctx->opad[i] = (uint8_t)(ctx->opad[i] ^ key[i]); 320 | } 321 | 322 | tiny_md5_starts(ctx); 323 | tiny_md5_update(ctx, ctx->ipad, 64); 324 | 325 | memset(sum, 0, sizeof(sum)); 326 | } 327 | 328 | /* 329 | * MD5 HMAC process buffer 330 | */ 331 | void tiny_md5_hmac_update(tiny_md5_context * ctx, uint8_t *input, int ilen) 332 | { 333 | tiny_md5_update(ctx, input, ilen); 334 | } 335 | 336 | /* 337 | * MD5 HMAC final digest 338 | */ 339 | void tiny_md5_hmac_finish(tiny_md5_context * ctx, uint8_t output[16]) 340 | { 341 | uint8_t tmpbuf[16]; 342 | 343 | tiny_md5_finish(ctx, tmpbuf); 344 | tiny_md5_starts(ctx); 345 | tiny_md5_update(ctx, ctx->opad, 64); 346 | tiny_md5_update(ctx, tmpbuf, 16); 347 | tiny_md5_finish(ctx, output); 348 | 349 | memset(tmpbuf, 0, sizeof(tmpbuf)); 350 | } 351 | 352 | /* 353 | * output = HMAC-MD5( hmac key, input buffer ) 354 | */ 355 | void tiny_md5_hmac(uint8_t *key, int keylen, uint8_t *input, int ilen, 356 | uint8_t output[16]) 357 | { 358 | tiny_md5_context ctx; 359 | 360 | tiny_md5_hmac_starts(&ctx, key, keylen); 361 | tiny_md5_hmac_update(&ctx, input, ilen); 362 | tiny_md5_hmac_finish(&ctx, output); 363 | 364 | memset(&ctx, 0, sizeof(tiny_md5_context)); 365 | } 366 | 367 | #endif 368 | -------------------------------------------------------------------------------- /src/tiny_sha1.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FIPS-180-1 compliant SHA-1 implementation 3 | * 4 | * Based on TropicSSL: Copyright (C) 2017 Shanghai Real-Thread Technology Co., Ltd 5 | * 6 | * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine 7 | * 8 | * Copyright (C) 2009 Paul Bakker 9 | * 10 | * All rights reserved. 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions 14 | * are met: 15 | * 16 | * * Redistributions of source code must retain the above copyright 17 | * notice, this list of conditions and the following disclaimer. 18 | * * Redistributions in binary form must reproduce the above copyright 19 | * notice, this list of conditions and the following disclaimer in the 20 | * documentation and/or other materials provided with the distribution. 21 | * * Neither the names of PolarSSL or XySSL nor the names of its contributors 22 | * may be used to endorse or promote products derived from this software 23 | * without specific prior written permission. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 28 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 31 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | */ 37 | /* 38 | * The SHA-1 standard was published by NIST in 1993. 39 | * 40 | * http://www.itl.nist.gov/fipspubs/fip180-1.htm 41 | */ 42 | 43 | #include "tinycrypt_config.h" 44 | 45 | #if defined(TINY_CRYPT_SHA1) 46 | 47 | #include "tinycrypt.h" 48 | 49 | #include 50 | #include 51 | 52 | /* 53 | * 32-bit integer manipulation macros (big endian) 54 | */ 55 | #ifndef GET_ULONG_BE 56 | #define GET_ULONG_BE(n,b,i) \ 57 | { \ 58 | (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ 59 | | ( (uint32_t) (b)[(i) + 1] << 16 ) \ 60 | | ( (uint32_t) (b)[(i) + 2] << 8 ) \ 61 | | ( (uint32_t) (b)[(i) + 3] ); \ 62 | } 63 | #endif 64 | 65 | #ifndef PUT_ULONG_BE 66 | #define PUT_ULONG_BE(n,b,i) \ 67 | { \ 68 | (b)[(i) ] = (uint8_t) ( (n) >> 24 ); \ 69 | (b)[(i) + 1] = (uint8_t) ( (n) >> 16 ); \ 70 | (b)[(i) + 2] = (uint8_t) ( (n) >> 8 ); \ 71 | (b)[(i) + 3] = (uint8_t) ( (n) ); \ 72 | } 73 | #endif 74 | 75 | /* 76 | * SHA-1 context setup 77 | */ 78 | void tiny_sha1_starts(tiny_sha1_context * ctx) 79 | { 80 | ctx->total[0] = 0; 81 | ctx->total[1] = 0; 82 | 83 | ctx->state[0] = 0x67452301; 84 | ctx->state[1] = 0xEFCDAB89; 85 | ctx->state[2] = 0x98BADCFE; 86 | ctx->state[3] = 0x10325476; 87 | ctx->state[4] = 0xC3D2E1F0; 88 | } 89 | 90 | static void sha1_process(tiny_sha1_context * ctx, uint8_t data[64]) 91 | { 92 | uint32_t temp, W[16], A, B, C, D, E; 93 | 94 | GET_ULONG_BE(W[0], data, 0); 95 | GET_ULONG_BE(W[1], data, 4); 96 | GET_ULONG_BE(W[2], data, 8); 97 | GET_ULONG_BE(W[3], data, 12); 98 | GET_ULONG_BE(W[4], data, 16); 99 | GET_ULONG_BE(W[5], data, 20); 100 | GET_ULONG_BE(W[6], data, 24); 101 | GET_ULONG_BE(W[7], data, 28); 102 | GET_ULONG_BE(W[8], data, 32); 103 | GET_ULONG_BE(W[9], data, 36); 104 | GET_ULONG_BE(W[10], data, 40); 105 | GET_ULONG_BE(W[11], data, 44); 106 | GET_ULONG_BE(W[12], data, 48); 107 | GET_ULONG_BE(W[13], data, 52); 108 | GET_ULONG_BE(W[14], data, 56); 109 | GET_ULONG_BE(W[15], data, 60); 110 | 111 | #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) 112 | 113 | #define R(t) \ 114 | ( \ 115 | temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ 116 | W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ 117 | ( W[t & 0x0F] = S(temp,1) ) \ 118 | ) 119 | 120 | #define P(a,b,c,d,e,x) \ 121 | { \ 122 | e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ 123 | } 124 | 125 | A = ctx->state[0]; 126 | B = ctx->state[1]; 127 | C = ctx->state[2]; 128 | D = ctx->state[3]; 129 | E = ctx->state[4]; 130 | 131 | #define F(x,y,z) (z ^ (x & (y ^ z))) 132 | #define K 0x5A827999 133 | 134 | P(A, B, C, D, E, W[0]); 135 | P(E, A, B, C, D, W[1]); 136 | P(D, E, A, B, C, W[2]); 137 | P(C, D, E, A, B, W[3]); 138 | P(B, C, D, E, A, W[4]); 139 | P(A, B, C, D, E, W[5]); 140 | P(E, A, B, C, D, W[6]); 141 | P(D, E, A, B, C, W[7]); 142 | P(C, D, E, A, B, W[8]); 143 | P(B, C, D, E, A, W[9]); 144 | P(A, B, C, D, E, W[10]); 145 | P(E, A, B, C, D, W[11]); 146 | P(D, E, A, B, C, W[12]); 147 | P(C, D, E, A, B, W[13]); 148 | P(B, C, D, E, A, W[14]); 149 | P(A, B, C, D, E, W[15]); 150 | P(E, A, B, C, D, R(16)); 151 | P(D, E, A, B, C, R(17)); 152 | P(C, D, E, A, B, R(18)); 153 | P(B, C, D, E, A, R(19)); 154 | 155 | #undef K 156 | #undef F 157 | 158 | #define F(x,y,z) (x ^ y ^ z) 159 | #define K 0x6ED9EBA1 160 | 161 | P(A, B, C, D, E, R(20)); 162 | P(E, A, B, C, D, R(21)); 163 | P(D, E, A, B, C, R(22)); 164 | P(C, D, E, A, B, R(23)); 165 | P(B, C, D, E, A, R(24)); 166 | P(A, B, C, D, E, R(25)); 167 | P(E, A, B, C, D, R(26)); 168 | P(D, E, A, B, C, R(27)); 169 | P(C, D, E, A, B, R(28)); 170 | P(B, C, D, E, A, R(29)); 171 | P(A, B, C, D, E, R(30)); 172 | P(E, A, B, C, D, R(31)); 173 | P(D, E, A, B, C, R(32)); 174 | P(C, D, E, A, B, R(33)); 175 | P(B, C, D, E, A, R(34)); 176 | P(A, B, C, D, E, R(35)); 177 | P(E, A, B, C, D, R(36)); 178 | P(D, E, A, B, C, R(37)); 179 | P(C, D, E, A, B, R(38)); 180 | P(B, C, D, E, A, R(39)); 181 | 182 | #undef K 183 | #undef F 184 | 185 | #define F(x,y,z) ((x & y) | (z & (x | y))) 186 | #define K 0x8F1BBCDC 187 | 188 | P(A, B, C, D, E, R(40)); 189 | P(E, A, B, C, D, R(41)); 190 | P(D, E, A, B, C, R(42)); 191 | P(C, D, E, A, B, R(43)); 192 | P(B, C, D, E, A, R(44)); 193 | P(A, B, C, D, E, R(45)); 194 | P(E, A, B, C, D, R(46)); 195 | P(D, E, A, B, C, R(47)); 196 | P(C, D, E, A, B, R(48)); 197 | P(B, C, D, E, A, R(49)); 198 | P(A, B, C, D, E, R(50)); 199 | P(E, A, B, C, D, R(51)); 200 | P(D, E, A, B, C, R(52)); 201 | P(C, D, E, A, B, R(53)); 202 | P(B, C, D, E, A, R(54)); 203 | P(A, B, C, D, E, R(55)); 204 | P(E, A, B, C, D, R(56)); 205 | P(D, E, A, B, C, R(57)); 206 | P(C, D, E, A, B, R(58)); 207 | P(B, C, D, E, A, R(59)); 208 | 209 | #undef K 210 | #undef F 211 | 212 | #define F(x,y,z) (x ^ y ^ z) 213 | #define K 0xCA62C1D6 214 | 215 | P(A, B, C, D, E, R(60)); 216 | P(E, A, B, C, D, R(61)); 217 | P(D, E, A, B, C, R(62)); 218 | P(C, D, E, A, B, R(63)); 219 | P(B, C, D, E, A, R(64)); 220 | P(A, B, C, D, E, R(65)); 221 | P(E, A, B, C, D, R(66)); 222 | P(D, E, A, B, C, R(67)); 223 | P(C, D, E, A, B, R(68)); 224 | P(B, C, D, E, A, R(69)); 225 | P(A, B, C, D, E, R(70)); 226 | P(E, A, B, C, D, R(71)); 227 | P(D, E, A, B, C, R(72)); 228 | P(C, D, E, A, B, R(73)); 229 | P(B, C, D, E, A, R(74)); 230 | P(A, B, C, D, E, R(75)); 231 | P(E, A, B, C, D, R(76)); 232 | P(D, E, A, B, C, R(77)); 233 | P(C, D, E, A, B, R(78)); 234 | P(B, C, D, E, A, R(79)); 235 | 236 | #undef K 237 | #undef F 238 | 239 | ctx->state[0] += A; 240 | ctx->state[1] += B; 241 | ctx->state[2] += C; 242 | ctx->state[3] += D; 243 | ctx->state[4] += E; 244 | } 245 | 246 | /* 247 | * SHA-1 process buffer 248 | */ 249 | void tiny_sha1_update(tiny_sha1_context * ctx, uint8_t *input, int ilen) 250 | { 251 | int fill; 252 | uint32_t left; 253 | 254 | if (ilen <= 0) 255 | return; 256 | 257 | left = ctx->total[0] & 0x3F; 258 | fill = 64 - left; 259 | 260 | ctx->total[0] += ilen; 261 | ctx->total[0] &= 0xFFFFFFFF; 262 | 263 | if (ctx->total[0] < (uint32_t)ilen) 264 | ctx->total[1]++; 265 | 266 | if (left && ilen >= fill) { 267 | memcpy((void *)(ctx->buffer + left), (void *)input, fill); 268 | sha1_process(ctx, ctx->buffer); 269 | input += fill; 270 | ilen -= fill; 271 | left = 0; 272 | } 273 | 274 | while (ilen >= 64) { 275 | sha1_process(ctx, input); 276 | input += 64; 277 | ilen -= 64; 278 | } 279 | 280 | if (ilen > 0) { 281 | memcpy((void *)(ctx->buffer + left), (void *)input, ilen); 282 | } 283 | } 284 | 285 | static const uint8_t sha1_padding[64] = { 286 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 287 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 288 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 289 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 290 | }; 291 | 292 | /* 293 | * SHA-1 final digest 294 | */ 295 | void tiny_sha1_finish(tiny_sha1_context * ctx, uint8_t output[20]) 296 | { 297 | uint32_t last, padn; 298 | uint32_t high, low; 299 | uint8_t msglen[8]; 300 | 301 | high = (ctx->total[0] >> 29) 302 | | (ctx->total[1] << 3); 303 | low = (ctx->total[0] << 3); 304 | 305 | PUT_ULONG_BE(high, msglen, 0); 306 | PUT_ULONG_BE(low, msglen, 4); 307 | 308 | last = ctx->total[0] & 0x3F; 309 | padn = (last < 56) ? (56 - last) : (120 - last); 310 | 311 | tiny_sha1_update(ctx, (uint8_t *)sha1_padding, padn); 312 | tiny_sha1_update(ctx, msglen, 8); 313 | 314 | PUT_ULONG_BE(ctx->state[0], output, 0); 315 | PUT_ULONG_BE(ctx->state[1], output, 4); 316 | PUT_ULONG_BE(ctx->state[2], output, 8); 317 | PUT_ULONG_BE(ctx->state[3], output, 12); 318 | PUT_ULONG_BE(ctx->state[4], output, 16); 319 | } 320 | 321 | /* 322 | * output = SHA-1( input buffer ) 323 | */ 324 | void tiny_sha1(uint8_t *input, int ilen, uint8_t output[20]) 325 | { 326 | tiny_sha1_context ctx; 327 | 328 | tiny_sha1_starts(&ctx); 329 | tiny_sha1_update(&ctx, input, ilen); 330 | tiny_sha1_finish(&ctx, output); 331 | 332 | memset(&ctx, 0, sizeof(tiny_sha1_context)); 333 | } 334 | 335 | /* 336 | * SHA-1 HMAC context setup 337 | */ 338 | void tiny_sha1_hmac_starts(tiny_sha1_context * ctx, uint8_t *key, int keylen) 339 | { 340 | int i; 341 | uint8_t sum[20]; 342 | 343 | if (keylen > 64) { 344 | tiny_sha1(key, keylen, sum); 345 | keylen = 20; 346 | key = sum; 347 | } 348 | 349 | memset(ctx->ipad, 0x36, 64); 350 | memset(ctx->opad, 0x5C, 64); 351 | 352 | for (i = 0; i < keylen; i++) { 353 | ctx->ipad[i] = (uint8_t)(ctx->ipad[i] ^ key[i]); 354 | ctx->opad[i] = (uint8_t)(ctx->opad[i] ^ key[i]); 355 | } 356 | 357 | tiny_sha1_starts(ctx); 358 | tiny_sha1_update(ctx, ctx->ipad, 64); 359 | 360 | memset(sum, 0, sizeof(sum)); 361 | } 362 | 363 | /* 364 | * SHA-1 HMAC process buffer 365 | */ 366 | void tiny_sha1_hmac_update(tiny_sha1_context * ctx, uint8_t *input, int ilen) 367 | { 368 | tiny_sha1_update(ctx, input, ilen); 369 | } 370 | 371 | /* 372 | * SHA-1 HMAC final digest 373 | */ 374 | void tiny_sha1_hmac_finish(tiny_sha1_context * ctx, uint8_t output[20]) 375 | { 376 | uint8_t tmpbuf[20]; 377 | 378 | tiny_sha1_finish(ctx, tmpbuf); 379 | tiny_sha1_starts(ctx); 380 | tiny_sha1_update(ctx, ctx->opad, 64); 381 | tiny_sha1_update(ctx, tmpbuf, 20); 382 | tiny_sha1_finish(ctx, output); 383 | 384 | memset(tmpbuf, 0, sizeof(tmpbuf)); 385 | } 386 | 387 | /* 388 | * output = HMAC-SHA-1( hmac key, input buffer ) 389 | */ 390 | void tiny_sha1_hmac(uint8_t *key, int keylen, 391 | uint8_t *input, int ilen, uint8_t output[20]) 392 | { 393 | tiny_sha1_context ctx; 394 | 395 | tiny_sha1_hmac_starts(&ctx, key, keylen); 396 | tiny_sha1_hmac_update(&ctx, input, ilen); 397 | tiny_sha1_hmac_finish(&ctx, output); 398 | 399 | memset(&ctx, 0, sizeof(tiny_sha1_context)); 400 | } 401 | 402 | #endif 403 | -------------------------------------------------------------------------------- /src/tiny_sha2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * FIPS-180-2 compliant SHA-256 implementation 3 | * 4 | * Based on TropicSSL: Copyright (C) 2017 Shanghai Real-Thread Technology Co., Ltd 5 | * 6 | * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine 7 | * 8 | * Copyright (C) 2009 Paul Bakker 9 | * 10 | * All rights reserved. 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions 14 | * are met: 15 | * 16 | * * Redistributions of source code must retain the above copyright 17 | * notice, this list of conditions and the following disclaimer. 18 | * * Redistributions in binary form must reproduce the above copyright 19 | * notice, this list of conditions and the following disclaimer in the 20 | * documentation and/or other materials provided with the distribution. 21 | * * Neither the names of PolarSSL or XySSL nor the names of its contributors 22 | * may be used to endorse or promote products derived from this software 23 | * without specific prior written permission. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 28 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 31 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | */ 37 | /* 38 | * The SHA-256 Secure Hash Standard was published by NIST in 2002. 39 | * 40 | * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf 41 | */ 42 | 43 | #include "tinycrypt_config.h" 44 | 45 | #if defined(TINY_CRYPT_SHA256) 46 | 47 | #include "tinycrypt.h" 48 | 49 | #include 50 | #include 51 | 52 | /* 53 | * 32-bit integer manipulation macros (big endian) 54 | */ 55 | #ifndef GET_ULONG_BE 56 | #define GET_ULONG_BE(n,b,i) \ 57 | { \ 58 | (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ 59 | | ( (uint32_t) (b)[(i) + 1] << 16 ) \ 60 | | ( (uint32_t) (b)[(i) + 2] << 8 ) \ 61 | | ( (uint32_t) (b)[(i) + 3] ); \ 62 | } 63 | #endif 64 | 65 | #ifndef PUT_ULONG_BE 66 | #define PUT_ULONG_BE(n,b,i) \ 67 | { \ 68 | (b)[(i) ] = (uint8_t) ( (n) >> 24 ); \ 69 | (b)[(i) + 1] = (uint8_t) ( (n) >> 16 ); \ 70 | (b)[(i) + 2] = (uint8_t) ( (n) >> 8 ); \ 71 | (b)[(i) + 3] = (uint8_t) ( (n) ); \ 72 | } 73 | #endif 74 | 75 | /* 76 | * SHA-256 context setup 77 | */ 78 | void tiny_sha2_starts(tiny_sha2_context * ctx, int is224) 79 | { 80 | ctx->total[0] = 0; 81 | ctx->total[1] = 0; 82 | 83 | if (is224 == 0) { 84 | /* SHA-256 */ 85 | ctx->state[0] = 0x6A09E667; 86 | ctx->state[1] = 0xBB67AE85; 87 | ctx->state[2] = 0x3C6EF372; 88 | ctx->state[3] = 0xA54FF53A; 89 | ctx->state[4] = 0x510E527F; 90 | ctx->state[5] = 0x9B05688C; 91 | ctx->state[6] = 0x1F83D9AB; 92 | ctx->state[7] = 0x5BE0CD19; 93 | } else { 94 | /* SHA-224 */ 95 | ctx->state[0] = 0xC1059ED8; 96 | ctx->state[1] = 0x367CD507; 97 | ctx->state[2] = 0x3070DD17; 98 | ctx->state[3] = 0xF70E5939; 99 | ctx->state[4] = 0xFFC00B31; 100 | ctx->state[5] = 0x68581511; 101 | ctx->state[6] = 0x64F98FA7; 102 | ctx->state[7] = 0xBEFA4FA4; 103 | } 104 | 105 | ctx->is224 = is224; 106 | } 107 | 108 | static void sha2_process(tiny_sha2_context * ctx, uint8_t data[64]) 109 | { 110 | uint32_t temp1, temp2, W[64]; 111 | uint32_t A, B, C, D, E, F, G, H; 112 | 113 | GET_ULONG_BE(W[0], data, 0); 114 | GET_ULONG_BE(W[1], data, 4); 115 | GET_ULONG_BE(W[2], data, 8); 116 | GET_ULONG_BE(W[3], data, 12); 117 | GET_ULONG_BE(W[4], data, 16); 118 | GET_ULONG_BE(W[5], data, 20); 119 | GET_ULONG_BE(W[6], data, 24); 120 | GET_ULONG_BE(W[7], data, 28); 121 | GET_ULONG_BE(W[8], data, 32); 122 | GET_ULONG_BE(W[9], data, 36); 123 | GET_ULONG_BE(W[10], data, 40); 124 | GET_ULONG_BE(W[11], data, 44); 125 | GET_ULONG_BE(W[12], data, 48); 126 | GET_ULONG_BE(W[13], data, 52); 127 | GET_ULONG_BE(W[14], data, 56); 128 | GET_ULONG_BE(W[15], data, 60); 129 | 130 | #define SHR(x,n) ((x & 0xFFFFFFFF) >> n) 131 | #define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) 132 | 133 | #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) 134 | #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) 135 | 136 | #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) 137 | #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) 138 | 139 | #define F0(x,y,z) ((x & y) | (z & (x | y))) 140 | #define F1(x,y,z) (z ^ (x & (y ^ z))) 141 | 142 | #define R(t) \ 143 | ( \ 144 | W[t] = S1(W[t - 2]) + W[t - 7] + \ 145 | S0(W[t - 15]) + W[t - 16] \ 146 | ) 147 | 148 | #define P(a,b,c,d,e,f,g,h,x,K) \ 149 | { \ 150 | temp1 = h + S3(e) + F1(e,f,g) + K + x; \ 151 | temp2 = S2(a) + F0(a,b,c); \ 152 | d += temp1; h = temp1 + temp2; \ 153 | } 154 | 155 | A = ctx->state[0]; 156 | B = ctx->state[1]; 157 | C = ctx->state[2]; 158 | D = ctx->state[3]; 159 | E = ctx->state[4]; 160 | F = ctx->state[5]; 161 | G = ctx->state[6]; 162 | H = ctx->state[7]; 163 | 164 | P(A, B, C, D, E, F, G, H, W[0], 0x428A2F98); 165 | P(H, A, B, C, D, E, F, G, W[1], 0x71374491); 166 | P(G, H, A, B, C, D, E, F, W[2], 0xB5C0FBCF); 167 | P(F, G, H, A, B, C, D, E, W[3], 0xE9B5DBA5); 168 | P(E, F, G, H, A, B, C, D, W[4], 0x3956C25B); 169 | P(D, E, F, G, H, A, B, C, W[5], 0x59F111F1); 170 | P(C, D, E, F, G, H, A, B, W[6], 0x923F82A4); 171 | P(B, C, D, E, F, G, H, A, W[7], 0xAB1C5ED5); 172 | P(A, B, C, D, E, F, G, H, W[8], 0xD807AA98); 173 | P(H, A, B, C, D, E, F, G, W[9], 0x12835B01); 174 | P(G, H, A, B, C, D, E, F, W[10], 0x243185BE); 175 | P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3); 176 | P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74); 177 | P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE); 178 | P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7); 179 | P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174); 180 | P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1); 181 | P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786); 182 | P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6); 183 | P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC); 184 | P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F); 185 | P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA); 186 | P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC); 187 | P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA); 188 | P(A, B, C, D, E, F, G, H, R(24), 0x983E5152); 189 | P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D); 190 | P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8); 191 | P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7); 192 | P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3); 193 | P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147); 194 | P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351); 195 | P(B, C, D, E, F, G, H, A, R(31), 0x14292967); 196 | P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85); 197 | P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138); 198 | P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC); 199 | P(F, G, H, A, B, C, D, E, R(35), 0x53380D13); 200 | P(E, F, G, H, A, B, C, D, R(36), 0x650A7354); 201 | P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB); 202 | P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E); 203 | P(B, C, D, E, F, G, H, A, R(39), 0x92722C85); 204 | P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1); 205 | P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B); 206 | P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70); 207 | P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3); 208 | P(E, F, G, H, A, B, C, D, R(44), 0xD192E819); 209 | P(D, E, F, G, H, A, B, C, R(45), 0xD6990624); 210 | P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585); 211 | P(B, C, D, E, F, G, H, A, R(47), 0x106AA070); 212 | P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116); 213 | P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08); 214 | P(G, H, A, B, C, D, E, F, R(50), 0x2748774C); 215 | P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5); 216 | P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3); 217 | P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A); 218 | P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F); 219 | P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3); 220 | P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE); 221 | P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F); 222 | P(G, H, A, B, C, D, E, F, R(58), 0x84C87814); 223 | P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208); 224 | P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA); 225 | P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB); 226 | P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7); 227 | P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2); 228 | 229 | ctx->state[0] += A; 230 | ctx->state[1] += B; 231 | ctx->state[2] += C; 232 | ctx->state[3] += D; 233 | ctx->state[4] += E; 234 | ctx->state[5] += F; 235 | ctx->state[6] += G; 236 | ctx->state[7] += H; 237 | } 238 | 239 | /* 240 | * SHA-256 process buffer 241 | */ 242 | void tiny_sha2_update(tiny_sha2_context * ctx, uint8_t *input, int ilen) 243 | { 244 | int fill; 245 | uint32_t left; 246 | 247 | if (ilen <= 0) 248 | return; 249 | 250 | left = ctx->total[0] & 0x3F; 251 | fill = 64 - left; 252 | 253 | ctx->total[0] += ilen; 254 | ctx->total[0] &= 0xFFFFFFFF; 255 | 256 | if (ctx->total[0] < (uint32_t)ilen) 257 | ctx->total[1]++; 258 | 259 | if (left && ilen >= fill) { 260 | memcpy((void *)(ctx->buffer + left), (void *)input, fill); 261 | sha2_process(ctx, ctx->buffer); 262 | input += fill; 263 | ilen -= fill; 264 | left = 0; 265 | } 266 | 267 | while (ilen >= 64) { 268 | sha2_process(ctx, input); 269 | input += 64; 270 | ilen -= 64; 271 | } 272 | 273 | if (ilen > 0) { 274 | memcpy((void *)(ctx->buffer + left), (void *)input, ilen); 275 | } 276 | } 277 | 278 | static const uint8_t sha2_padding[64] = { 279 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 280 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 281 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 283 | }; 284 | 285 | /* 286 | * SHA-256 final digest 287 | */ 288 | void tiny_sha2_finish(tiny_sha2_context * ctx, uint8_t output[32]) 289 | { 290 | uint32_t last, padn; 291 | uint32_t high, low; 292 | uint8_t msglen[8]; 293 | 294 | high = (ctx->total[0] >> 29) 295 | | (ctx->total[1] << 3); 296 | low = (ctx->total[0] << 3); 297 | 298 | PUT_ULONG_BE(high, msglen, 0); 299 | PUT_ULONG_BE(low, msglen, 4); 300 | 301 | last = ctx->total[0] & 0x3F; 302 | padn = (last < 56) ? (56 - last) : (120 - last); 303 | 304 | tiny_sha2_update(ctx, (uint8_t *)sha2_padding, padn); 305 | tiny_sha2_update(ctx, msglen, 8); 306 | 307 | PUT_ULONG_BE(ctx->state[0], output, 0); 308 | PUT_ULONG_BE(ctx->state[1], output, 4); 309 | PUT_ULONG_BE(ctx->state[2], output, 8); 310 | PUT_ULONG_BE(ctx->state[3], output, 12); 311 | PUT_ULONG_BE(ctx->state[4], output, 16); 312 | PUT_ULONG_BE(ctx->state[5], output, 20); 313 | PUT_ULONG_BE(ctx->state[6], output, 24); 314 | 315 | if (ctx->is224 == 0) 316 | PUT_ULONG_BE(ctx->state[7], output, 28); 317 | } 318 | 319 | /* 320 | * output = SHA-256( input buffer ) 321 | */ 322 | void tiny_sha2(uint8_t *input, int ilen, uint8_t output[32], int is224) 323 | { 324 | tiny_sha2_context ctx; 325 | 326 | tiny_sha2_starts(&ctx, is224); 327 | tiny_sha2_update(&ctx, input, ilen); 328 | tiny_sha2_finish(&ctx, output); 329 | 330 | memset(&ctx, 0, sizeof(tiny_sha2_context)); 331 | } 332 | 333 | /* 334 | * SHA-256 HMAC context setup 335 | */ 336 | void tiny_sha2_hmac_starts(tiny_sha2_context * ctx, uint8_t *key, int keylen, 337 | int is224) 338 | { 339 | int i; 340 | uint8_t sum[32]; 341 | 342 | if (keylen > 64) { 343 | tiny_sha2(key, keylen, sum, is224); 344 | keylen = (is224) ? 28 : 32; 345 | key = sum; 346 | } 347 | 348 | memset(ctx->ipad, 0x36, 64); 349 | memset(ctx->opad, 0x5C, 64); 350 | 351 | for (i = 0; i < keylen; i++) { 352 | ctx->ipad[i] = (uint8_t)(ctx->ipad[i] ^ key[i]); 353 | ctx->opad[i] = (uint8_t)(ctx->opad[i] ^ key[i]); 354 | } 355 | 356 | tiny_sha2_starts(ctx, is224); 357 | tiny_sha2_update(ctx, ctx->ipad, 64); 358 | 359 | memset(sum, 0, sizeof(sum)); 360 | } 361 | 362 | /* 363 | * SHA-256 HMAC process buffer 364 | */ 365 | void tiny_sha2_hmac_update(tiny_sha2_context * ctx, uint8_t *input, int ilen) 366 | { 367 | tiny_sha2_update(ctx, input, ilen); 368 | } 369 | 370 | /* 371 | * SHA-256 HMAC final digest 372 | */ 373 | void tiny_sha2_hmac_finish(tiny_sha2_context * ctx, uint8_t output[32]) 374 | { 375 | int is224, hlen; 376 | uint8_t tmpbuf[32]; 377 | 378 | is224 = ctx->is224; 379 | hlen = (is224 == 0) ? 32 : 28; 380 | 381 | tiny_sha2_finish(ctx, tmpbuf); 382 | tiny_sha2_starts(ctx, is224); 383 | tiny_sha2_update(ctx, ctx->opad, 64); 384 | tiny_sha2_update(ctx, tmpbuf, hlen); 385 | tiny_sha2_finish(ctx, output); 386 | 387 | memset(tmpbuf, 0, sizeof(tmpbuf)); 388 | } 389 | 390 | /* 391 | * output = HMAC-SHA-256( hmac key, input buffer ) 392 | */ 393 | void tiny_sha2_hmac(uint8_t *key, int keylen, 394 | uint8_t *input, int ilen, 395 | uint8_t output[32], int is224) 396 | { 397 | tiny_sha2_context ctx; 398 | 399 | tiny_sha2_hmac_starts(&ctx, key, keylen, is224); 400 | tiny_sha2_hmac_update(&ctx, input, ilen); 401 | tiny_sha2_hmac_finish(&ctx, output); 402 | 403 | memset(&ctx, 0, sizeof(tiny_sha2_context)); 404 | } 405 | 406 | #endif 407 | --------------------------------------------------------------------------------