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  * @{
21  */
22 
23 #if defined(WITH_POSIX) || (defined(WITH_LWIP) && !defined(LWIP_RAND))
24 #include <stdlib.h>
25 
26 /**
27  * Fills \p buf with \p len random bytes. This is the default implementation for
28  * prng(). You might want to change prng() to use a better PRNG on your specific
29  * platform.
30  */
31 static inline int
coap_prng_impl(unsigned char * buf,size_t len)32 coap_prng_impl(unsigned char *buf, size_t len) {
33   while (len--)
34     *buf++ = rand() & 0xFF;
35   return 1;
36 }
37 #endif /* WITH_POSIX */
38 
39 #ifdef WITH_CONTIKI
40 #include <string.h>
41 
42 /**
43  * Fills \p buf with \p len random bytes. This is the default implementation for
44  * prng(). You might want to change prng() to use a better PRNG on your specific
45  * platform.
46  */
47 static inline int
contiki_prng_impl(unsigned char * buf,size_t len)48 contiki_prng_impl(unsigned char *buf, size_t len) {
49   unsigned short v = random_rand();
50   while (len > sizeof(v)) {
51     memcpy(buf, &v, sizeof(v));
52     len -= sizeof(v);
53     buf += sizeof(v);
54     v = random_rand();
55   }
56 
57   memcpy(buf, &v, len);
58   return 1;
59 }
60 
61 #define prng(Buf,Length) contiki_prng_impl((Buf), (Length))
62 #define prng_init(Value) random_init((unsigned short)(Value))
63 #endif /* WITH_CONTIKI */
64 
65 #if defined(WITH_LWIP) && defined(LWIP_RAND)
66 static inline int
lwip_prng_impl(unsigned char * buf,size_t len)67 lwip_prng_impl(unsigned char *buf, size_t len) {
68   u32_t v = LWIP_RAND();
69   while (len > sizeof(v)) {
70     memcpy(buf, &v, sizeof(v));
71     len -= sizeof(v);
72     buf += sizeof(v);
73     v = LWIP_RAND();
74   }
75 
76   memcpy(buf, &v, len);
77   return 1;
78 }
79 
80 #define prng(Buf,Length) lwip_prng_impl((Buf), (Length))
81 #define prng_init(Value)
82 
83 #endif /* WITH_LWIP */
84 
85 #ifndef prng
86 /**
87  * Fills \p Buf with \p Length bytes of random data.
88  *
89  * @hideinitializer
90  */
91 #define prng(Buf,Length) coap_prng_impl((Buf), (Length))
92 #endif
93 
94 #ifndef prng_init
95 /**
96  * Called to set the PRNG seed. You may want to re-define this to allow for a
97  * better PRNG.
98  *
99  * @hideinitializer
100  */
101 #define prng_init(Value) srand((unsigned long)(Value))
102 #endif
103 
104 /** @} */
105 
106 #endif /* _COAP_PRNG_H_ */
107