• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  *  @brief CTR-PRNG initialization procedure
83  *  Initializes prng context with entropy and personalization string (if any)
84  *  @return returns TC_CRYPTO_SUCCESS (1)
85  *          returns TC_CRYPTO_FAIL (0) if:
86  *                ctx == NULL,
87  *                entropy == NULL,
88  *                entropyLen < (TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE)
89  *  @note       Only the first (TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE) bytes of
90  *              both the entropy and personalization inputs are used -
91  *              supplying additional bytes has no effect.
92  *  @param ctx IN/OUT -- the PRNG context to initialize
93  *  @param entropy IN -- entropy used to seed the PRNG
94  *  @param entropyLen IN -- entropy length in bytes
95  *  @param personalization IN -- personalization string used to seed the PRNG
96  *  (may be null)
97  *  @param plen IN -- personalization length in bytes
98  *
99  */
100 int tc_ctr_prng_init(TCCtrPrng_t *const ctx,
101                      uint8_t const *const entropy,
102                      unsigned int entropyLen,
103                      uint8_t const *const personalization,
104                      unsigned int pLen);
105 
106 /**
107  *  @brief CTR-PRNG reseed procedure
108  *  Mixes entropy and additional_input into the prng context
109  *  @return returns  TC_CRYPTO_SUCCESS (1)
110  *  returns TC_CRYPTO_FAIL (0) if:
111  *          ctx == NULL,
112  *          entropy == NULL,
113  *          entropylen < (TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE)
114  *  @note It is better to reseed an existing prng context rather than
115  *        re-initialise, so that any existing entropy in the context is
116  *        presereved.  This offers some protection against undetected failures
117  *        of the entropy source.
118  *  @note Assumes tc_ctr_prng_init has been called for ctx
119  *  @param ctx IN/OUT -- the PRNG state
120  *  @param entropy IN -- entropy to mix into the prng
121  *  @param entropylen IN -- length of entropy in bytes
122  *  @param additional_input IN -- additional input to the prng (may be null)
123  *  @param additionallen IN -- additional input length in bytes
124  */
125 int tc_ctr_prng_reseed(TCCtrPrng_t *const ctx,
126                        uint8_t const *const entropy,
127                        unsigned int entropyLen,
128                        uint8_t const *const additional_input,
129                        unsigned int additionallen);
130 
131 /**
132  *  @brief CTR-PRNG generate procedure
133  *  Generates outlen pseudo-random bytes into out buffer, updates prng
134  *  @return returns TC_CRYPTO_SUCCESS (1)
135  *          returns TC_CTR_PRNG_RESEED_REQ (-1) if a reseed is needed
136  *             returns TC_CRYPTO_FAIL (0) if:
137  *                ctx == NULL,
138  *                out == NULL,
139  *                outlen >= 2^16
140  *  @note Assumes tc_ctr_prng_init has been called for ctx
141  *  @param ctx IN/OUT -- the PRNG context
142  *  @param additional_input IN -- additional input to the prng (may be null)
143  *  @param additionallen IN -- additional input length in bytes
144  *  @param out IN/OUT -- buffer to receive output
145  *  @param outlen IN -- size of out buffer in bytes
146  */
147 int tc_ctr_prng_generate(TCCtrPrng_t *const ctx,
148                          uint8_t const *const additional_input,
149                          unsigned int additionallen,
150                          uint8_t *const out,
151                          unsigned int outlen);
152 
153 /**
154  *  @brief CTR-PRNG uninstantiate procedure
155  *  Zeroes the internal state of the supplied prng context
156  *  @return none
157  *  @param ctx IN/OUT -- the PRNG context
158  */
159 void tc_ctr_prng_uninstantiate(TCCtrPrng_t *const ctx);
160 
161 #ifdef __cplusplus
162 }
163 #endif
164 
165 #endif /* __TC_CTR_PRNG_H__ */
166