1 /*
2 * prng.h -- Pseudo Random Numbers
3 *
4 * Copyright (C) 2010-2011 Olaf Bergmann <bergmann@tzi.org>
5 *
6 * This file is part of the CoAP library libcoap. Please see README for terms
7 * of use.
8 */
9
10 /**
11 * @file prng.h
12 * @brief Pseudo Random Numbers
13 */
14
15 #ifndef COAP_PRNG_H_
16 #define COAP_PRNG_H_
17
18 /**
19 * @defgroup prng Pseudo Random Numbers
20 * API functions for gerating pseudo random numbers
21 * @{
22 */
23
24 #if defined(WITH_CONTIKI)
25 #include <string.h>
26
27 /**
28 * Fills \p buf with \p len random bytes. This is the default implementation for
29 * prng(). You might want to change prng() to use a better PRNG on your specific
30 * platform.
31 */
32 COAP_STATIC_INLINE int
contiki_prng_impl(unsigned char * buf,size_t len)33 contiki_prng_impl(unsigned char *buf, size_t len) {
34 uint16_t v = random_rand();
35 while (len > sizeof(v)) {
36 memcpy(buf, &v, sizeof(v));
37 len -= sizeof(v);
38 buf += sizeof(v);
39 v = random_rand();
40 }
41
42 memcpy(buf, &v, len);
43 return 1;
44 }
45
46 #define prng(Buf,Length) contiki_prng_impl((Buf), (Length))
47 #define prng_init(Value) random_init((uint16_t)(Value))
48 #elif defined(WITH_LWIP) && defined(LWIP_RAND)
49 COAP_STATIC_INLINE int
lwip_prng_impl(unsigned char * buf,size_t len)50 lwip_prng_impl(unsigned char *buf, size_t len) {
51 u32_t v = LWIP_RAND();
52 while (len > sizeof(v)) {
53 memcpy(buf, &v, sizeof(v));
54 len -= sizeof(v);
55 buf += sizeof(v);
56 v = LWIP_RAND();
57 }
58
59 memcpy(buf, &v, len);
60 return 1;
61 }
62
63 #define prng(Buf,Length) lwip_prng_impl((Buf), (Length))
64 #define prng_init(Value)
65 #elif defined(_WIN32)
66 #define prng_init(Value)
67 errno_t __cdecl rand_s( _Out_ unsigned int* _RandomValue );
68 /**
69 * Fills \p buf with \p len random bytes. This is the default implementation for
70 * prng(). You might want to change prng() to use a better PRNG on your specific
71 * platform.
72 */
73 COAP_STATIC_INLINE int
coap_prng_impl(unsigned char * buf,size_t len)74 coap_prng_impl( unsigned char *buf, size_t len ) {
75 while ( len != 0 ) {
76 uint32_t r = 0;
77 size_t i;
78 if ( rand_s( &r ) != 0 )
79 return 0;
80 for ( i = 0; i < len && i < 4; i++ ) {
81 *buf++ = (uint8_t)r;
82 r >>= 8;
83 }
84 len -= i;
85 }
86 return 1;
87 }
88
89 #else
90 #include <stdlib.h>
91
92 /**
93 * Fills \p buf with \p len random bytes. This is the default implementation for
94 * prng(). You might want to change prng() to use a better PRNG on your specific
95 * platform.
96 */
97 COAP_STATIC_INLINE int
coap_prng_impl(unsigned char * buf,size_t len)98 coap_prng_impl( unsigned char *buf, size_t len ) {
99 while ( len-- )
100 *buf++ = rand() & 0xFF;
101 return 1;
102 }
103 #endif
104
105
106 #ifndef prng
107 /**
108 * Fills \p Buf with \p Length bytes of random data.
109 *
110 * @hideinitializer
111 */
112 #define prng(Buf,Length) coap_prng_impl((Buf), (Length))
113 #endif
114
115 #ifndef prng_init
116 /**
117 * Called to set the PRNG seed. You may want to re-define this to allow for a
118 * better PRNG.
119 *
120 * @hideinitializer
121 */
122 #define prng_init(Value) srand((unsigned long)(Value))
123 #endif
124
125 /** @} */
126
127 #endif /* COAP_PRNG_H_ */
128