• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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