blob: b3349546df6efdc8874e474c3be685135633d9bc [file] [log] [blame]
Paul Bakkere07c4312013-07-03 14:00:49 +02001#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
2#include "polarssl/memory.h"
3#endif
4
Manuel Pégourié-Gonnard74468332013-10-21 13:56:40 +02005#if defined(WANT_NOT_RND_MPI)
6#if defined(POLARSSL_BIGNUM_C)
7#include "polarssl/bignum.h"
8#else
9#error "not_rnd_mpi() need bignum.c"
10#endif
11#endif
12
Paul Bakkerb3dcbc12011-03-13 16:57:25 +000013#ifdef _MSC_VER
14#include <basetsd.h>
15typedef UINT32 uint32_t;
16#else
17#include <inttypes.h>
18#endif
19
Paul Bakker19343182013-08-16 13:31:10 +020020#include <assert.h>
21#include <stdlib.h>
22#include <string.h>
23
Paul Bakkerb3dcbc12011-03-13 16:57:25 +000024/*
25 * 32-bit integer manipulation macros (big endian)
26 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000027#ifndef GET_UINT32_BE
28#define GET_UINT32_BE(n,b,i) \
Paul Bakkerb3dcbc12011-03-13 16:57:25 +000029{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000030 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
31 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
32 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
33 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakkerb3dcbc12011-03-13 16:57:25 +000034}
35#endif
36
Paul Bakker5c2364c2012-10-01 14:41:15 +000037#ifndef PUT_UINT32_BE
38#define PUT_UINT32_BE(n,b,i) \
Paul Bakkerb3dcbc12011-03-13 16:57:25 +000039{ \
40 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
41 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
42 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
43 (b)[(i) + 3] = (unsigned char) ( (n) ); \
44}
45#endif
46
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +020047static int unhexify(unsigned char *obuf, const char *ibuf)
Paul Bakker367dae42009-06-28 21:50:27 +000048{
49 unsigned char c, c2;
50 int len = strlen(ibuf) / 2;
51 assert(!(strlen(ibuf) %1)); // must be even number of bytes
52
53 while (*ibuf != 0)
54 {
55 c = *ibuf++;
56 if( c >= '0' && c <= '9' )
57 c -= '0';
58 else if( c >= 'a' && c <= 'f' )
59 c -= 'a' - 10;
60 else if( c >= 'A' && c <= 'F' )
61 c -= 'A' - 10;
62 else
63 assert( 0 );
64
65 c2 = *ibuf++;
66 if( c2 >= '0' && c2 <= '9' )
67 c2 -= '0';
68 else if( c2 >= 'a' && c2 <= 'f' )
69 c2 -= 'a' - 10;
70 else if( c2 >= 'A' && c2 <= 'F' )
71 c2 -= 'A' - 10;
72 else
73 assert( 0 );
74
75 *obuf++ = ( c << 4 ) | c2;
76 }
77
78 return len;
79}
80
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +020081static void hexify(unsigned char *obuf, const unsigned char *ibuf, int len)
Paul Bakker367dae42009-06-28 21:50:27 +000082{
83 unsigned char l, h;
84
85 while (len != 0)
86 {
87 h = (*ibuf) / 16;
88 l = (*ibuf) % 16;
89
90 if( h < 10 )
91 *obuf++ = '0' + h;
92 else
93 *obuf++ = 'a' + h - 10;
94
95 if( l < 10 )
96 *obuf++ = '0' + l;
97 else
98 *obuf++ = 'a' + l - 10;
99
100 ++ibuf;
101 len--;
102 }
103}
Paul Bakker9dcc3222011-03-08 14:16:06 +0000104
105/**
106 * This function just returns data from rand().
Paul Bakker997bbd12011-03-13 15:45:42 +0000107 * Although predictable and often similar on multiple
108 * runs, this does not result in identical random on
109 * each run. So do not use this if the results of a
110 * test depend on the random data that is generated.
Paul Bakker9dcc3222011-03-08 14:16:06 +0000111 *
112 * rng_state shall be NULL.
113 */
Paul Bakkera3d195c2011-11-27 21:07:34 +0000114static int rnd_std_rand( void *rng_state, unsigned char *output, size_t len )
Paul Bakker9dcc3222011-03-08 14:16:06 +0000115{
Paul Bakkera3d195c2011-11-27 21:07:34 +0000116 size_t i;
117
Paul Bakker9dcc3222011-03-08 14:16:06 +0000118 if( rng_state != NULL )
119 rng_state = NULL;
120
Paul Bakkera3d195c2011-11-27 21:07:34 +0000121 for( i = 0; i < len; ++i )
122 output[i] = rand();
123
124 return( 0 );
Paul Bakker9dcc3222011-03-08 14:16:06 +0000125}
126
127/**
128 * This function only returns zeros
129 *
130 * rng_state shall be NULL.
131 */
Paul Bakkera3d195c2011-11-27 21:07:34 +0000132static int rnd_zero_rand( void *rng_state, unsigned char *output, size_t len )
Paul Bakker9dcc3222011-03-08 14:16:06 +0000133{
134 if( rng_state != NULL )
135 rng_state = NULL;
136
Paul Bakkera3d195c2011-11-27 21:07:34 +0000137 memset( output, 0, len );
138
Paul Bakker9dcc3222011-03-08 14:16:06 +0000139 return( 0 );
140}
141
142typedef struct
143{
144 unsigned char *buf;
Paul Bakkera3d195c2011-11-27 21:07:34 +0000145 size_t length;
Paul Bakker997bbd12011-03-13 15:45:42 +0000146} rnd_buf_info;
Paul Bakker9dcc3222011-03-08 14:16:06 +0000147
148/**
149 * This function returns random based on a buffer it receives.
150 *
Paul Bakker997bbd12011-03-13 15:45:42 +0000151 * rng_state shall be a pointer to a rnd_buf_info structure.
152 *
153 * The number of bytes released from the buffer on each call to
154 * the random function is specified by per_call. (Can be between
155 * 1 and 4)
Paul Bakker9dcc3222011-03-08 14:16:06 +0000156 *
157 * After the buffer is empty it will return rand();
158 */
Paul Bakkera3d195c2011-11-27 21:07:34 +0000159static int rnd_buffer_rand( void *rng_state, unsigned char *output, size_t len )
Paul Bakker9dcc3222011-03-08 14:16:06 +0000160{
Paul Bakker997bbd12011-03-13 15:45:42 +0000161 rnd_buf_info *info = (rnd_buf_info *) rng_state;
Paul Bakkera3d195c2011-11-27 21:07:34 +0000162 size_t use_len;
Paul Bakker9dcc3222011-03-08 14:16:06 +0000163
164 if( rng_state == NULL )
Paul Bakkera3d195c2011-11-27 21:07:34 +0000165 return( rnd_std_rand( NULL, output, len ) );
Paul Bakker9dcc3222011-03-08 14:16:06 +0000166
Paul Bakkera3d195c2011-11-27 21:07:34 +0000167 use_len = len;
168 if( len > info->length )
169 use_len = info->length;
Paul Bakker997bbd12011-03-13 15:45:42 +0000170
Paul Bakkera3d195c2011-11-27 21:07:34 +0000171 if( use_len )
Paul Bakker9dcc3222011-03-08 14:16:06 +0000172 {
Paul Bakkera3d195c2011-11-27 21:07:34 +0000173 memcpy( output, info->buf, use_len );
174 info->buf += use_len;
175 info->length -= use_len;
Paul Bakker9dcc3222011-03-08 14:16:06 +0000176 }
177
Paul Bakkera3d195c2011-11-27 21:07:34 +0000178 if( len - use_len > 0 )
179 return( rnd_std_rand( NULL, output + use_len, len - use_len ) );
180
181 return( 0 );
Paul Bakker9dcc3222011-03-08 14:16:06 +0000182}
Paul Bakker997bbd12011-03-13 15:45:42 +0000183
184/**
185 * Info structure for the pseudo random function
186 *
187 * Key should be set at the start to a test-unique value.
Paul Bakkerb3dcbc12011-03-13 16:57:25 +0000188 * Do not forget endianness!
Paul Bakker997bbd12011-03-13 15:45:42 +0000189 * State( v0, v1 ) should be set to zero.
190 */
191typedef struct
192{
Paul Bakkerb3dcbc12011-03-13 16:57:25 +0000193 uint32_t key[16];
Paul Bakker997bbd12011-03-13 15:45:42 +0000194 uint32_t v0, v1;
195} rnd_pseudo_info;
196
197/**
198 * This function returns random based on a pseudo random function.
199 * This means the results should be identical on all systems.
200 * Pseudo random is based on the XTEA encryption algorithm to
201 * generate pseudorandom.
202 *
203 * rng_state shall be a pointer to a rnd_pseudo_info structure.
204 */
Paul Bakkera3d195c2011-11-27 21:07:34 +0000205static int rnd_pseudo_rand( void *rng_state, unsigned char *output, size_t len )
Paul Bakker997bbd12011-03-13 15:45:42 +0000206{
207 rnd_pseudo_info *info = (rnd_pseudo_info *) rng_state;
Paul Bakkera3d195c2011-11-27 21:07:34 +0000208 uint32_t i, *k, sum, delta=0x9E3779B9;
Paul Bakker40dd5302012-05-15 15:02:38 +0000209 unsigned char result[4];
Paul Bakker997bbd12011-03-13 15:45:42 +0000210
211 if( rng_state == NULL )
Paul Bakkera3d195c2011-11-27 21:07:34 +0000212 return( rnd_std_rand( NULL, output, len ) );
Paul Bakker997bbd12011-03-13 15:45:42 +0000213
Paul Bakkerb3dcbc12011-03-13 16:57:25 +0000214 k = info->key;
Paul Bakkera3d195c2011-11-27 21:07:34 +0000215
216 while( len > 0 )
Paul Bakker997bbd12011-03-13 15:45:42 +0000217 {
Paul Bakker40dd5302012-05-15 15:02:38 +0000218 size_t use_len = ( len > 4 ) ? 4 : len;
Paul Bakkera3d195c2011-11-27 21:07:34 +0000219 sum = 0;
220
Paul Bakkera3d195c2011-11-27 21:07:34 +0000221 for( i = 0; i < 32; i++ )
222 {
223 info->v0 += (((info->v1 << 4) ^ (info->v1 >> 5)) + info->v1) ^ (sum + k[sum & 3]);
224 sum += delta;
225 info->v1 += (((info->v0 << 4) ^ (info->v0 >> 5)) + info->v0) ^ (sum + k[(sum>>11) & 3]);
226 }
227
Paul Bakker5c2364c2012-10-01 14:41:15 +0000228 PUT_UINT32_BE( info->v0, result, 0 );
Paul Bakker40dd5302012-05-15 15:02:38 +0000229 memcpy( output, result, use_len );
Paul Bakkera3d195c2011-11-27 21:07:34 +0000230 len -= use_len;
Paul Bakker997bbd12011-03-13 15:45:42 +0000231 }
232
Paul Bakkera3d195c2011-11-27 21:07:34 +0000233 return( 0 );
Paul Bakker997bbd12011-03-13 15:45:42 +0000234}
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100235
Manuel Pégourié-Gonnard74468332013-10-21 13:56:40 +0200236#if defined(WANT_NOT_RND_MPI)
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100237/**
Manuel Pégourié-Gonnard74468332013-10-21 13:56:40 +0200238 * NOT random function, to match test vectors.
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100239 *
Manuel Pégourié-Gonnard74468332013-10-21 13:56:40 +0200240 * The following are equivalent:
241 * mpi_fill_random( x, strlen( str ) / 2, not_rnd, str );
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100242 * mpi_read_string( x, 16, str );
Manuel Pégourié-Gonnard74468332013-10-21 13:56:40 +0200243 * Warning: no other use is supported!
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100244 */
Manuel Pégourié-Gonnard74468332013-10-21 13:56:40 +0200245#define ciL (sizeof(t_uint)) /* chars in limb */
246#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL)
247static int not_rnd_mpi( void *in, unsigned char *out, size_t len )
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100248{
Manuel Pégourié-Gonnard74468332013-10-21 13:56:40 +0200249 char *str = (char *) in;
250 mpi X;
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100251
Manuel Pégourié-Gonnard74468332013-10-21 13:56:40 +0200252 /*
253 * The 'in' pointer we get is from an MPI prepared by mpi_fill_random(),
254 * just reconstruct the rest in order to be able to call mpi_read_string()
255 */
256 X.s = 1;
257 X.p = (t_uint *) out;
258 X.n = CHARS_TO_LIMBS( len );
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100259
Manuel Pégourié-Gonnard74468332013-10-21 13:56:40 +0200260 /*
261 * If str is too long, mpi_read_string() will try to allocate a new buffer
262 * for X.p, which we want to avoid at all costs.
263 */
264 assert( strlen( str ) / 2 == len );
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100265
Manuel Pégourié-Gonnard74468332013-10-21 13:56:40 +0200266 return( mpi_read_string( &X, 16, str ) );
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100267}
Manuel Pégourié-Gonnard74468332013-10-21 13:56:40 +0200268#endif /* WANT_NOT_RND_MPI */