xref: /nrf52832-nimble/packages/NimBLE-latest/ext/tinycrypt/include/tinycrypt/ctr_prng.h (revision 042d53a763ad75cb1465103098bb88c245d95138)
1 /* ctr_prng.h - TinyCrypt interface to a CTR-PRNG implementation */
2 
3 /*
4  * Copyright (c) 2016, Chris Morrison
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * * Redistributions of source code must retain the above copyright notice, this
11  *   list of conditions and the following disclaimer.
12  *
13  * * Redistributions in binary form must reproduce the above copyright notice,
14  *   this list of conditions and the following disclaimer in the documentation
15  *   and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 /**
31  * @file
32  * @brief Interface to a CTR-PRNG implementation.
33  *
34  *  Overview:   A pseudo-random number generator (PRNG) generates a sequence
35  *              of numbers that have a distribution close to the one expected
36  *              for a sequence of truly random numbers. The NIST Special
37  *              Publication 800-90A specifies several mechanisms to generate
38  *              sequences of pseudo random numbers, including the CTR-PRNG one
39  *              which is based on AES. TinyCrypt implements CTR-PRNG with
40  *              AES-128.
41  *
42  *  Security:   A cryptographically secure PRNG depends on the existence of an
43  *              entropy source to provide a truly random seed as well as the
44  *              security of the primitives used as the building blocks (AES-128
45  *              in this instance).
46  *
47  *  Requires:   - AES-128
48  *
49  *  Usage:      1) call tc_ctr_prng_init to seed the prng context
50  *
51  *              2) call tc_ctr_prng_reseed to mix in additional entropy into
52  *              the prng context
53  *
54  *              3) call tc_ctr_prng_generate to output the pseudo-random data
55  *
56  *              4) call tc_ctr_prng_uninstantiate to zero out the prng context
57  */
58 
59 #ifndef __TC_CTR_PRNG_H__
60 #define __TC_CTR_PRNG_H__
61 
62 #include <tinycrypt/aes.h>
63 
64 #define TC_CTR_PRNG_RESEED_REQ -1
65 
66 #ifdef __cplusplus
67 extern "C" {
68 #endif
69 
70 typedef struct {
71 	/* updated each time another BLOCKLEN_BYTES bytes are produced */
72 	uint8_t V[TC_AES_BLOCK_SIZE];
73 
74 	/* updated whenever the PRNG is reseeded */
75 	struct tc_aes_key_sched_struct key;
76 
77 	/* number of requests since initialization/reseeding */
78 	uint64_t reseedCount;
79 } TCCtrPrng_t;
80 
81 
82 /**
83  *  @brief CTR-PRNG initialization procedure
84  *  Initializes prng context with entropy and personalization string (if any)
85  *  @return returns TC_CRYPTO_SUCCESS (1)
86  *          returns TC_CRYPTO_FAIL (0) if:
87  *                ctx == NULL,
88  *                entropy == NULL,
89  *                entropyLen < (TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE)
90  *  @note       Only the first (TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE) bytes of
91  *              both the entropy and personalization inputs are used -
92  *              supplying additional bytes has no effect.
93  *  @param ctx IN/OUT -- the PRNG context to initialize
94  *  @param entropy IN -- entropy used to seed the PRNG
95  *  @param entropyLen IN -- entropy length in bytes
96  *  @param personalization IN -- personalization string used to seed the PRNG
97  *  (may be null)
98  *  @param plen IN -- personalization length in bytes
99  *
100  */
101 int tc_ctr_prng_init(TCCtrPrng_t * const ctx,
102 		     uint8_t const * const entropy,
103 		     unsigned int entropyLen,
104 		     uint8_t const * const personalization,
105 		     unsigned int pLen);
106 
107 /**
108  *  @brief CTR-PRNG reseed procedure
109  *  Mixes entropy and additional_input into the prng context
110  *  @return returns  TC_CRYPTO_SUCCESS (1)
111  *  returns TC_CRYPTO_FAIL (0) if:
112  *          ctx == NULL,
113  *          entropy == NULL,
114  *          entropylen < (TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE)
115  *  @note It is better to reseed an existing prng context rather than
116  *        re-initialise, so that any existing entropy in the context is
117  *        presereved.  This offers some protection against undetected failures
118  *        of the entropy source.
119  *  @note Assumes tc_ctr_prng_init has been called for ctx
120  *  @param ctx IN/OUT -- the PRNG state
121  *  @param entropy IN -- entropy to mix into the prng
122  *  @param entropylen IN -- length of entropy in bytes
123  *  @param additional_input IN -- additional input to the prng (may be null)
124  *  @param additionallen IN -- additional input length in bytes
125  */
126 int tc_ctr_prng_reseed(TCCtrPrng_t * const ctx,
127 		       uint8_t const * const entropy,
128 		       unsigned int entropyLen,
129 		       uint8_t const * const additional_input,
130 		       unsigned int additionallen);
131 
132 /**
133  *  @brief CTR-PRNG generate procedure
134  *  Generates outlen pseudo-random bytes into out buffer, updates prng
135  *  @return returns TC_CRYPTO_SUCCESS (1)
136  *          returns TC_CTR_PRNG_RESEED_REQ (-1) if a reseed is needed
137  *             returns TC_CRYPTO_FAIL (0) if:
138  *                ctx == NULL,
139  *                out == NULL,
140  *                outlen >= 2^16
141  *  @note Assumes tc_ctr_prng_init has been called for ctx
142  *  @param ctx IN/OUT -- the PRNG context
143  *  @param additional_input IN -- additional input to the prng (may be null)
144  *  @param additionallen IN -- additional input length in bytes
145  *  @param out IN/OUT -- buffer to receive output
146  *  @param outlen IN -- size of out buffer in bytes
147  */
148 int tc_ctr_prng_generate(TCCtrPrng_t * const ctx,
149 			 uint8_t const * const additional_input,
150 			 unsigned int additionallen,
151 			 uint8_t * const out,
152 			 unsigned int outlen);
153 
154 /**
155  *  @brief CTR-PRNG uninstantiate procedure
156  *  Zeroes the internal state of the supplied prng context
157  *  @return none
158  *  @param ctx IN/OUT -- the PRNG context
159  */
160 void tc_ctr_prng_uninstantiate(TCCtrPrng_t * const ctx);
161 
162 #ifdef __cplusplus
163 }
164 #endif
165 
166 #endif /* __TC_CTR_PRNG_H__ */
167