Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: MiniTLS-HTTPS-Example
crypto_prng.c
00001 /* 00002 MiniTLS - A super trimmed down TLS/SSL Library for embedded devices 00003 Author: Donatien Garnier 00004 Copyright (C) 2013-2014 AppNearMe Ltd 00005 00006 This program is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU General Public License 00008 as published by the Free Software Foundation; either version 2 00009 of the License, or (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 *//** 00020 * \file crypto_prng.c 00021 * \copyright Copyright (c) AppNearMe Ltd 2013 00022 * \author Donatien Garnier 00023 */ 00024 00025 #define __DEBUG__ 0//4 00026 #ifndef __MODULE__ 00027 #define __MODULE__ "crypto_prng.c" 00028 #endif 00029 00030 #include "core/fwk.h" 00031 #include "inc/minitls_errors.h" 00032 #include "crypto_prng.h" 00033 00034 #include "crypto_aes_128.h" 00035 #include "crypto_sha1.h" 00036 00037 #define YARROW_REGENERATE_VALUE 10 00038 00039 static void crypto_prng_update_internal(crypto_prng_t* prng); 00040 00041 void crypto_prng_init(crypto_prng_t* prng, rtos_mtx_t* mtx) 00042 { 00043 memset(prng->pool, 0, SHA1_SIZE); 00044 prng->counter = 0xFFFFFFFFUL; //Will force update 00045 prng->mtx = mtx; 00046 prng->buf_pos = AES_128_BLOCK_SIZE; //invalidate buffer 00047 prng->fed = false; 00048 } 00049 00050 #define LOCK() do{ if(prng->mtx) { rtos_mtx_lock(prng->mtx); } }while(0) 00051 #define UNLOCK() do{ if(prng->mtx) { rtos_mtx_unlock(prng->mtx); } }while(0) 00052 00053 void crypto_prng_feed(crypto_prng_t* prng, uint8_t* data, size_t size) 00054 { 00055 LOCK(); 00056 //Update pool 00057 crypto_sha1_t hash; 00058 crypto_sha1_init(&hash); 00059 crypto_sha1_update(&hash, prng->pool, SHA1_SIZE); 00060 crypto_sha1_update(&hash, data, size); 00061 crypto_sha1_end(&hash, prng->pool); 00062 prng->fed = true; 00063 UNLOCK(); 00064 } 00065 00066 void crypto_prng_update_internal(crypto_prng_t* prng) 00067 { 00068 if(!prng->fed) 00069 { 00070 //Rehash the pool to "rotate" key 00071 crypto_sha1_t hash; 00072 crypto_sha1_init(&hash); 00073 crypto_sha1_update(&hash, prng->pool, SHA1_SIZE); 00074 crypto_sha1_end(&hash, prng->pool); 00075 } 00076 prng->fed = false; 00077 //Generate key from pool 00078 crypto_aes_128_init(&prng->cipher, prng->pool, expand_encryption_key); //OK because AES_128_BLOCK_SIZE < SHA1_SIZE 00079 prng->counter = 0; 00080 } 00081 00082 void crypto_prng_update(crypto_prng_t* prng) 00083 { 00084 LOCK(); 00085 crypto_prng_update_internal(prng); 00086 UNLOCK(); 00087 } 00088 00089 void crypto_prng_get(crypto_prng_t* prng, uint8_t* data, size_t size) 00090 { 00091 LOCK(); 00092 00093 //Regenerate data as needed 00094 while(size > 0) 00095 { 00096 if(prng->counter > YARROW_REGENERATE_VALUE) 00097 { 00098 crypto_prng_update_internal(prng); 00099 } 00100 00101 //Copy any remaining data from buffer 00102 size_t cpy_size = MIN(size, AES_128_BLOCK_SIZE - prng->buf_pos); 00103 memcpy(data, prng->buf + prng->buf_pos, cpy_size); 00104 data += cpy_size; 00105 size -= cpy_size; 00106 prng->buf_pos += cpy_size; 00107 00108 if(prng->buf_pos >= AES_128_BLOCK_SIZE) 00109 { 00110 memset(prng->buf + sizeof(uint32_t), 0, AES_128_BLOCK_SIZE - sizeof(uint32_t)); 00111 memcpy(prng->buf, &prng->counter, sizeof(uint32_t)); //We do not care about endianness as long as it's consistent (don't know of any system which would swap endianness during the execution of a program...) 00112 crypto_aes_128_encrypt(&prng->cipher, prng->buf, prng->buf); 00113 prng->counter++; 00114 prng->buf_pos = 0; 00115 } 00116 } 00117 00118 UNLOCK(); 00119 } 00120 00121
Generated on Wed Jul 13 2022 00:22:54 by
1.7.2
