xref: /linux/crypto/df_sp80090a.c (revision a619fe35ab41fded440d3762d4fbad84ff86a4d4)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 /*
4  * NIST SP800-90A DRBG derivation function
5  *
6  * Copyright (C) 2014, Stephan Mueller <smueller@chronox.de>
7  */
8 
9 #include <linux/errno.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/string.h>
13 #include <crypto/aes.h>
14 #include <crypto/df_sp80090a.h>
15 #include <crypto/internal/drbg.h>
16 
17 static void drbg_kcapi_symsetkey(struct crypto_aes_ctx *aesctx,
18 				 const unsigned char *key,
19 				 u8 keylen);
drbg_kcapi_symsetkey(struct crypto_aes_ctx * aesctx,const unsigned char * key,u8 keylen)20 static void drbg_kcapi_symsetkey(struct crypto_aes_ctx *aesctx,
21 				 const unsigned char *key, u8 keylen)
22 {
23 	aes_expandkey(aesctx, key, keylen);
24 }
25 
drbg_kcapi_sym(struct crypto_aes_ctx * aesctx,unsigned char * outval,const struct drbg_string * in,u8 blocklen_bytes)26 static void drbg_kcapi_sym(struct crypto_aes_ctx *aesctx,
27 			   unsigned char *outval,
28 			   const struct drbg_string *in, u8 blocklen_bytes)
29 {
30 	/* there is only component in *in */
31 	BUG_ON(in->len < blocklen_bytes);
32 	aes_encrypt(aesctx, outval, in->buf);
33 }
34 
35 /* BCC function for CTR DRBG as defined in 10.4.3 */
36 
drbg_ctr_bcc(struct crypto_aes_ctx * aesctx,unsigned char * out,const unsigned char * key,struct list_head * in,u8 blocklen_bytes,u8 keylen)37 static void drbg_ctr_bcc(struct crypto_aes_ctx *aesctx,
38 			 unsigned char *out, const unsigned char *key,
39 			 struct list_head *in,
40 			 u8 blocklen_bytes,
41 			 u8 keylen)
42 {
43 	struct drbg_string *curr = NULL;
44 	struct drbg_string data;
45 	short cnt = 0;
46 
47 	drbg_string_fill(&data, out, blocklen_bytes);
48 
49 	/* 10.4.3 step 2 / 4 */
50 	drbg_kcapi_symsetkey(aesctx, key, keylen);
51 	list_for_each_entry(curr, in, list) {
52 		const unsigned char *pos = curr->buf;
53 		size_t len = curr->len;
54 		/* 10.4.3 step 4.1 */
55 		while (len) {
56 			/* 10.4.3 step 4.2 */
57 			if (blocklen_bytes == cnt) {
58 				cnt = 0;
59 				drbg_kcapi_sym(aesctx, out, &data, blocklen_bytes);
60 			}
61 			out[cnt] ^= *pos;
62 			pos++;
63 			cnt++;
64 			len--;
65 		}
66 	}
67 	/* 10.4.3 step 4.2 for last block */
68 	if (cnt)
69 		drbg_kcapi_sym(aesctx, out, &data, blocklen_bytes);
70 }
71 
72 /*
73  * scratchpad usage: drbg_ctr_update is interlinked with crypto_drbg_ctr_df
74  * (and drbg_ctr_bcc, but this function does not need any temporary buffers),
75  * the scratchpad is used as follows:
76  * drbg_ctr_update:
77  *	temp
78  *		start: drbg->scratchpad
79  *		length: drbg_statelen(drbg) + drbg_blocklen(drbg)
80  *			note: the cipher writing into this variable works
81  *			blocklen-wise. Now, when the statelen is not a multiple
82  *			of blocklen, the generateion loop below "spills over"
83  *			by at most blocklen. Thus, we need to give sufficient
84  *			memory.
85  *	df_data
86  *		start: drbg->scratchpad +
87  *				drbg_statelen(drbg) + drbg_blocklen(drbg)
88  *		length: drbg_statelen(drbg)
89  *
90  * crypto_drbg_ctr_df:
91  *	pad
92  *		start: df_data + drbg_statelen(drbg)
93  *		length: drbg_blocklen(drbg)
94  *	iv
95  *		start: pad + drbg_blocklen(drbg)
96  *		length: drbg_blocklen(drbg)
97  *	temp
98  *		start: iv + drbg_blocklen(drbg)
99  *		length: drbg_satelen(drbg) + drbg_blocklen(drbg)
100  *			note: temp is the buffer that the BCC function operates
101  *			on. BCC operates blockwise. drbg_statelen(drbg)
102  *			is sufficient when the DRBG state length is a multiple
103  *			of the block size. For AES192 (and maybe other ciphers)
104  *			this is not correct and the length for temp is
105  *			insufficient (yes, that also means for such ciphers,
106  *			the final output of all BCC rounds are truncated).
107  *			Therefore, add drbg_blocklen(drbg) to cover all
108  *			possibilities.
109  * refer to crypto_drbg_ctr_df_datalen() to get required length
110  */
111 
112 /* Derivation Function for CTR DRBG as defined in 10.4.2 */
crypto_drbg_ctr_df(struct crypto_aes_ctx * aesctx,unsigned char * df_data,size_t bytes_to_return,struct list_head * seedlist,u8 blocklen_bytes,u8 statelen)113 int crypto_drbg_ctr_df(struct crypto_aes_ctx *aesctx,
114 		       unsigned char *df_data, size_t bytes_to_return,
115 		       struct list_head *seedlist,
116 		       u8 blocklen_bytes,
117 		       u8 statelen)
118 {
119 	unsigned char L_N[8];
120 	/* S3 is input */
121 	struct drbg_string S1, S2, S4, cipherin;
122 	LIST_HEAD(bcc_list);
123 	unsigned char *pad = df_data + statelen;
124 	unsigned char *iv = pad + blocklen_bytes;
125 	unsigned char *temp = iv + blocklen_bytes;
126 	size_t padlen = 0;
127 	unsigned int templen = 0;
128 	/* 10.4.2 step 7 */
129 	unsigned int i = 0;
130 	/* 10.4.2 step 8 */
131 	const unsigned char *K = (unsigned char *)
132 			   "\x00\x01\x02\x03\x04\x05\x06\x07"
133 			   "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
134 			   "\x10\x11\x12\x13\x14\x15\x16\x17"
135 			   "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f";
136 	unsigned char *X;
137 	size_t generated_len = 0;
138 	size_t inputlen = 0;
139 	struct drbg_string *seed = NULL;
140 	u8 keylen;
141 
142 	memset(pad, 0, blocklen_bytes);
143 	memset(iv, 0, blocklen_bytes);
144 	keylen = statelen - blocklen_bytes;
145 	/* 10.4.2 step 1 is implicit as we work byte-wise */
146 
147 	/* 10.4.2 step 2 */
148 	if ((512 / 8) < bytes_to_return)
149 		return -EINVAL;
150 
151 	/* 10.4.2 step 2 -- calculate the entire length of all input data */
152 	list_for_each_entry(seed, seedlist, list)
153 		inputlen += seed->len;
154 	drbg_cpu_to_be32(inputlen, &L_N[0]);
155 
156 	/* 10.4.2 step 3 */
157 	drbg_cpu_to_be32(bytes_to_return, &L_N[4]);
158 
159 	/* 10.4.2 step 5: length is L_N, input_string, one byte, padding */
160 	padlen = (inputlen + sizeof(L_N) + 1) % (blocklen_bytes);
161 	/* wrap the padlen appropriately */
162 	if (padlen)
163 		padlen = blocklen_bytes - padlen;
164 	/*
165 	 * pad / padlen contains the 0x80 byte and the following zero bytes.
166 	 * As the calculated padlen value only covers the number of zero
167 	 * bytes, this value has to be incremented by one for the 0x80 byte.
168 	 */
169 	padlen++;
170 	pad[0] = 0x80;
171 
172 	/* 10.4.2 step 4 -- first fill the linked list and then order it */
173 	drbg_string_fill(&S1, iv, blocklen_bytes);
174 	list_add_tail(&S1.list, &bcc_list);
175 	drbg_string_fill(&S2, L_N, sizeof(L_N));
176 	list_add_tail(&S2.list, &bcc_list);
177 	list_splice_tail(seedlist, &bcc_list);
178 	drbg_string_fill(&S4, pad, padlen);
179 	list_add_tail(&S4.list, &bcc_list);
180 
181 	/* 10.4.2 step 9 */
182 	while (templen < (keylen + (blocklen_bytes))) {
183 		/*
184 		 * 10.4.2 step 9.1 - the padding is implicit as the buffer
185 		 * holds zeros after allocation -- even the increment of i
186 		 * is irrelevant as the increment remains within length of i
187 		 */
188 		drbg_cpu_to_be32(i, iv);
189 		/* 10.4.2 step 9.2 -- BCC and concatenation with temp */
190 		drbg_ctr_bcc(aesctx, temp + templen, K, &bcc_list,
191 			     blocklen_bytes, keylen);
192 		/* 10.4.2 step 9.3 */
193 		i++;
194 		templen += blocklen_bytes;
195 	}
196 
197 	/* 10.4.2 step 11 */
198 	X = temp + (keylen);
199 	drbg_string_fill(&cipherin, X, blocklen_bytes);
200 
201 	/* 10.4.2 step 12: overwriting of outval is implemented in next step */
202 
203 	/* 10.4.2 step 13 */
204 	drbg_kcapi_symsetkey(aesctx, temp, keylen);
205 	while (generated_len < bytes_to_return) {
206 		short blocklen = 0;
207 		/*
208 		 * 10.4.2 step 13.1: the truncation of the key length is
209 		 * implicit as the key is only drbg_blocklen in size based on
210 		 * the implementation of the cipher function callback
211 		 */
212 		drbg_kcapi_sym(aesctx, X, &cipherin, blocklen_bytes);
213 		blocklen = (blocklen_bytes <
214 				(bytes_to_return - generated_len)) ?
215 			    blocklen_bytes :
216 				(bytes_to_return - generated_len);
217 		/* 10.4.2 step 13.2 and 14 */
218 		memcpy(df_data + generated_len, X, blocklen);
219 		generated_len += blocklen;
220 	}
221 
222 	memset(iv, 0, blocklen_bytes);
223 	memset(temp, 0, statelen + blocklen_bytes);
224 	memset(pad, 0, blocklen_bytes);
225 	return 0;
226 }
227 EXPORT_SYMBOL_GPL(crypto_drbg_ctr_df);
228 
229 MODULE_IMPORT_NS("CRYPTO_INTERNAL");
230 MODULE_LICENSE("GPL v2");
231 MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
232 MODULE_DESCRIPTION("Derivation Function conformant to SP800-90A");
233