Update benchmark projects.
[bertos.git] / bertos / sec / util.h
1 #ifndef SEC_UTIL_H
2 #define SEC_UTIL_H
3
4 #include <cfg/macros.h>
5 #include <cfg/compiler.h>
6 #include <cfg/debug.h>
7 #include <string.h>
8
9 /**
10  * Purge local variables, by zeroing them.
11  *
12  * This can be used to clear stack from intermediate results in crypto
13  * calculations that might somehow be leaked.
14  */
15 #define PURGE(x) \
16         memset(&x, 0, sizeof(x))
17
18 /**
19  * Convert a generic "password" (low-diffused) to a generic "key"
20  * (high-diffused).
21  *
22  * In common terminology, a "password" is a key with weak cryptographic
23  * characteristics, such as commonly used password input by an user,
24  * which are usually short and use only a few different characters from
25  * the 0-255 byte range.
26  *
27  * This function derives a strong key from the password using a one-way
28  * process.
29  *
30  * \note Uses PBKDF2 as key-derivation function, with a fixed salt that
31  * changes for each Bertos project.
32  */
33 void password2key(const char *pwd, size_t pwd_len,
34                                   uint8_t *key, size_t key_len);
35
36 INLINE void xor_block_8(uint8_t *out,
37                 const uint8_t *in1, const uint8_t *in2, size_t len)
38 {
39         while (len--)
40                 *out++ = *in1++ ^ *in2++;
41 }
42
43 INLINE void xor_block_const_8(uint8_t *out,
44                         const uint8_t *in, uint8_t k, size_t len)
45 {
46         while (len--)
47                 *out++ = *in++ ^ k;
48 }
49
50 INLINE void xor_block_32(uint32_t *out, const uint32_t *in1,
51                                 const uint32_t *in2, size_t len)
52 {
53         size_t rem = (len & (sizeof(uint32_t) - 1));
54
55         len /= sizeof(uint32_t);
56         while (len--)
57                 *out++ = *in1++ ^ *in2++;
58         xor_block_8((uint8_t *)out,
59                 (const uint8_t *)in1, (const uint8_t *)in2, rem);
60 }
61
62 INLINE void xor_block_const_32(uint32_t *out, const uint32_t *in,
63                                         uint8_t k, size_t len)
64 {
65         uint32_t k32 = k | ((uint32_t)k << 8) |
66                         ((uint32_t)k << 16) | ((uint32_t)k << 24);
67         size_t rem = (len & (sizeof(uint32_t) - 1));
68
69         len /= sizeof(uint32_t);
70         while (len--)
71                 *out++ = *in++ ^ k32;
72         xor_block_const_8((uint8_t *)out, (const uint8_t *)in, k, rem);
73 }
74
75 /**
76  * Perform a bitwise xor between \a in and \a inout, and store
77  * the result into \a inout.
78  */
79 INLINE void xor_block(void *out, const void *in1, const void *in2, size_t len)
80 {
81         if (is_aligned(out, sizeof(uint32_t)) &&
82                         is_aligned(in1, sizeof(uint32_t)) &&
83                         is_aligned(in2, sizeof(uint32_t)))
84         {
85                 uint32_t *obuf = (uint32_t *)((size_t)out);
86                 const uint32_t *ibuf1 = (const uint32_t *)((size_t)in1);
87                 const uint32_t *ibuf2 = (const uint32_t *)((size_t)in2);
88
89                 xor_block_32(obuf, ibuf1, ibuf2, len);
90         }
91         else
92         {
93                 uint8_t *obuf = (uint8_t *)((size_t)out);
94                 const uint8_t *ibuf1 = (const uint8_t *)((size_t)in1);
95                 const uint8_t *ibuf2 = (const uint8_t *)((size_t)in2);
96
97                 xor_block_8(obuf, ibuf1, ibuf2, len);
98         }
99 }
100
101 /**
102  * Perform a bitwise xor over \a inout with constant \a k.
103  */
104 INLINE void xor_block_const(uint8_t *out, const uint8_t *in, uint8_t k, size_t len)
105 {
106         if (is_aligned(out, sizeof(uint32_t)) &&
107                         is_aligned(in, sizeof(uint32_t)))
108         {
109                 uint32_t *obuf = (uint32_t *)((size_t)out);
110                 const uint32_t *ibuf = (const uint32_t *)((size_t)in);
111
112                 xor_block_const_32(obuf, ibuf, k, len);
113         }
114         else
115         {
116                 uint8_t *obuf = (uint8_t *)((size_t)out);
117                 const uint8_t *ibuf = (const uint8_t *)((size_t)in);
118
119                 xor_block_const_8(obuf, ibuf, k, len);
120         }
121 }
122
123 #endif /* SEC_UTIL_H */