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.
Fork of MiniTLS-GPL by
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 Tue Jul 12 2022 19:20:10 by
1.7.2
