1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */ 2 /* SPDX-License-Identifier: Unlicense */ 3 #include "tomcrypt_private.h" 4 5 /** 6 @file yarrow.c 7 Yarrow PRNG, Tom St Denis 8 */ 9 10 #ifdef LTC_YARROW 11 12 const struct ltc_prng_descriptor yarrow_desc = 13 { 14 "yarrow", 64, 15 &yarrow_start, 16 &yarrow_add_entropy, 17 &yarrow_ready, 18 &yarrow_read, 19 &yarrow_done, 20 &yarrow_export, 21 &yarrow_import, 22 &yarrow_test 23 }; 24 25 /** 26 Start the PRNG 27 @param prng [out] The PRNG state to initialize 28 @return CRYPT_OK if successful 29 */ 30 int yarrow_start(prng_state *prng) 31 { 32 int err; 33 34 LTC_ARGCHK(prng != NULL); 35 prng->ready = 0; 36 37 /* these are the default hash/cipher combo used */ 38 #ifdef LTC_RIJNDAEL 39 #if LTC_YARROW_AES==0 40 prng->u.yarrow.cipher = register_cipher(&rijndael_enc_desc); 41 #elif LTC_YARROW_AES==1 42 prng->u.yarrow.cipher = register_cipher(&aes_enc_desc); 43 #elif LTC_YARROW_AES==2 44 prng->u.yarrow.cipher = register_cipher(&rijndael_desc); 45 #elif LTC_YARROW_AES==3 46 prng->u.yarrow.cipher = register_cipher(&aes_desc); 47 #endif 48 #elif defined(LTC_BLOWFISH) 49 prng->u.yarrow.cipher = register_cipher(&blowfish_desc); 50 #elif defined(LTC_TWOFISH) 51 prng->u.yarrow.cipher = register_cipher(&twofish_desc); 52 #elif defined(LTC_RC6) 53 prng->u.yarrow.cipher = register_cipher(&rc6_desc); 54 #elif defined(LTC_RC5) 55 prng->u.yarrow.cipher = register_cipher(&rc5_desc); 56 #elif defined(LTC_SAFERP) 57 prng->u.yarrow.cipher = register_cipher(&saferp_desc); 58 #elif defined(LTC_RC2) 59 prng->u.yarrow.cipher = register_cipher(&rc2_desc); 60 #elif defined(LTC_NOEKEON) 61 prng->u.yarrow.cipher = register_cipher(&noekeon_desc); 62 #elif defined(LTC_ANUBIS) 63 prng->u.yarrow.cipher = register_cipher(&anubis_desc); 64 #elif defined(LTC_KSEED) 65 prng->u.yarrow.cipher = register_cipher(&kseed_desc); 66 #elif defined(LTC_KHAZAD) 67 prng->u.yarrow.cipher = register_cipher(&khazad_desc); 68 #elif defined(LTC_CAST5) 69 prng->u.yarrow.cipher = register_cipher(&cast5_desc); 70 #elif defined(LTC_XTEA) 71 prng->u.yarrow.cipher = register_cipher(&xtea_desc); 72 #elif defined(LTC_SAFER) 73 prng->u.yarrow.cipher = register_cipher(&safer_sk128_desc); 74 #elif defined(LTC_DES) 75 prng->u.yarrow.cipher = register_cipher(&des3_desc); 76 #else 77 #error LTC_YARROW needs at least one CIPHER 78 #endif 79 if ((err = cipher_is_valid(prng->u.yarrow.cipher)) != CRYPT_OK) { 80 return err; 81 } 82 83 #ifdef LTC_SHA256 84 prng->u.yarrow.hash = register_hash(&sha256_desc); 85 #elif defined(LTC_SHA512) 86 prng->u.yarrow.hash = register_hash(&sha512_desc); 87 #elif defined(LTC_TIGER) 88 prng->u.yarrow.hash = register_hash(&tiger_desc); 89 #elif defined(LTC_SHA1) 90 prng->u.yarrow.hash = register_hash(&sha1_desc); 91 #elif defined(LTC_RIPEMD320) 92 prng->u.yarrow.hash = register_hash(&rmd320_desc); 93 #elif defined(LTC_RIPEMD256) 94 prng->u.yarrow.hash = register_hash(&rmd256_desc); 95 #elif defined(LTC_RIPEMD160) 96 prng->u.yarrow.hash = register_hash(&rmd160_desc); 97 #elif defined(LTC_RIPEMD128) 98 prng->u.yarrow.hash = register_hash(&rmd128_desc); 99 #elif defined(LTC_MD5) 100 prng->u.yarrow.hash = register_hash(&md5_desc); 101 #elif defined(LTC_MD4) 102 prng->u.yarrow.hash = register_hash(&md4_desc); 103 #elif defined(LTC_MD2) 104 prng->u.yarrow.hash = register_hash(&md2_desc); 105 #elif defined(LTC_WHIRLPOOL) 106 prng->u.yarrow.hash = register_hash(&whirlpool_desc); 107 #else 108 #error LTC_YARROW needs at least one HASH 109 #endif 110 if ((err = hash_is_valid(prng->u.yarrow.hash)) != CRYPT_OK) { 111 return err; 112 } 113 114 /* zero the memory used */ 115 zeromem(prng->u.yarrow.pool, sizeof(prng->u.yarrow.pool)); 116 LTC_MUTEX_INIT(&prng->lock) 117 118 return CRYPT_OK; 119 } 120 121 /** 122 Add entropy to the PRNG state 123 @param in The data to add 124 @param inlen Length of the data to add 125 @param prng PRNG state to update 126 @return CRYPT_OK if successful 127 */ 128 int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) 129 { 130 hash_state md; 131 int err; 132 133 LTC_ARGCHK(prng != NULL); 134 LTC_ARGCHK(in != NULL); 135 LTC_ARGCHK(inlen > 0); 136 137 LTC_MUTEX_LOCK(&prng->lock); 138 139 if ((err = hash_is_valid(prng->u.yarrow.hash)) != CRYPT_OK) { 140 goto LBL_UNLOCK; 141 } 142 143 /* start the hash */ 144 if ((err = hash_descriptor[prng->u.yarrow.hash]->init(&md)) != CRYPT_OK) { 145 goto LBL_UNLOCK; 146 } 147 148 /* hash the current pool */ 149 if ((err = hash_descriptor[prng->u.yarrow.hash]->process(&md, prng->u.yarrow.pool, 150 hash_descriptor[prng->u.yarrow.hash]->hashsize)) != CRYPT_OK) { 151 goto LBL_UNLOCK; 152 } 153 154 /* add the new entropy */ 155 if ((err = hash_descriptor[prng->u.yarrow.hash]->process(&md, in, inlen)) != CRYPT_OK) { 156 goto LBL_UNLOCK; 157 } 158 159 /* store result */ 160 err = hash_descriptor[prng->u.yarrow.hash]->done(&md, prng->u.yarrow.pool); 161 162 LBL_UNLOCK: 163 LTC_MUTEX_UNLOCK(&prng->lock); 164 return err; 165 } 166 167 /** 168 Make the PRNG ready to read from 169 @param prng The PRNG to make active 170 @return CRYPT_OK if successful 171 */ 172 int yarrow_ready(prng_state *prng) 173 { 174 int ks, err; 175 176 LTC_ARGCHK(prng != NULL); 177 178 LTC_MUTEX_LOCK(&prng->lock); 179 180 if ((err = hash_is_valid(prng->u.yarrow.hash)) != CRYPT_OK) { 181 goto LBL_UNLOCK; 182 } 183 184 if ((err = cipher_is_valid(prng->u.yarrow.cipher)) != CRYPT_OK) { 185 goto LBL_UNLOCK; 186 } 187 188 /* setup CTR mode using the "pool" as the key */ 189 ks = (int)hash_descriptor[prng->u.yarrow.hash]->hashsize; 190 if ((err = cipher_descriptor[prng->u.yarrow.cipher]->keysize(&ks)) != CRYPT_OK) { 191 goto LBL_UNLOCK; 192 } 193 194 if ((err = ctr_start(prng->u.yarrow.cipher, /* what cipher to use */ 195 prng->u.yarrow.pool, /* IV */ 196 prng->u.yarrow.pool, ks, /* KEY and key size */ 197 0, /* number of rounds */ 198 CTR_COUNTER_LITTLE_ENDIAN, /* little endian counter */ 199 &prng->u.yarrow.ctr)) != CRYPT_OK) { 200 goto LBL_UNLOCK; 201 } 202 prng->ready = 1; 203 204 LBL_UNLOCK: 205 LTC_MUTEX_UNLOCK(&prng->lock); 206 return err; 207 } 208 209 /** 210 Read from the PRNG 211 @param out Destination 212 @param outlen Length of output 213 @param prng The active PRNG to read from 214 @return Number of octets read 215 */ 216 unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng) 217 { 218 if (outlen == 0 || prng == NULL || out == NULL) return 0; 219 220 LTC_MUTEX_LOCK(&prng->lock); 221 222 if (!prng->ready) { 223 outlen = 0; 224 goto LBL_UNLOCK; 225 } 226 227 /* put out in predictable state first */ 228 zeromem(out, outlen); 229 230 /* now randomize it */ 231 if (ctr_encrypt(out, out, outlen, &prng->u.yarrow.ctr) != CRYPT_OK) { 232 outlen = 0; 233 } 234 235 LBL_UNLOCK: 236 LTC_MUTEX_UNLOCK(&prng->lock); 237 return outlen; 238 } 239 240 /** 241 Terminate the PRNG 242 @param prng The PRNG to terminate 243 @return CRYPT_OK if successful 244 */ 245 int yarrow_done(prng_state *prng) 246 { 247 int err; 248 LTC_ARGCHK(prng != NULL); 249 250 LTC_MUTEX_LOCK(&prng->lock); 251 prng->ready = 0; 252 253 /* call cipher done when we invent one ;-) */ 254 255 /* we invented one */ 256 err = ctr_done(&prng->u.yarrow.ctr); 257 258 LTC_MUTEX_UNLOCK(&prng->lock); 259 LTC_MUTEX_DESTROY(&prng->lock); 260 return err; 261 } 262 263 /** 264 Export the PRNG state 265 @param out [out] Destination 266 @param outlen [in/out] Max size and resulting size of the state 267 @param prng The PRNG to export 268 @return CRYPT_OK if successful 269 */ 270 LTC_PRNG_EXPORT(yarrow) 271 272 /** 273 Import a PRNG state 274 @param in The PRNG state 275 @param inlen Size of the state 276 @param prng The PRNG to import 277 @return CRYPT_OK if successful 278 */ 279 int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng) 280 { 281 int err; 282 283 LTC_ARGCHK(in != NULL); 284 LTC_ARGCHK(prng != NULL); 285 if (inlen < (unsigned long)yarrow_desc.export_size) return CRYPT_INVALID_ARG; 286 287 if ((err = yarrow_start(prng)) != CRYPT_OK) return err; 288 if ((err = yarrow_add_entropy(in, inlen, prng)) != CRYPT_OK) return err; 289 return CRYPT_OK; 290 } 291 292 /** 293 PRNG self-test 294 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled 295 */ 296 int yarrow_test(void) 297 { 298 #ifndef LTC_TEST 299 return CRYPT_NOP; 300 #else 301 int err; 302 prng_state prng; 303 304 if ((err = yarrow_start(&prng)) != CRYPT_OK) { 305 return err; 306 } 307 308 /* now let's test the hash/cipher that was chosen */ 309 if (cipher_descriptor[prng.u.yarrow.cipher]->test && 310 ((err = cipher_descriptor[prng.u.yarrow.cipher]->test()) != CRYPT_OK)) { 311 return err; 312 } 313 if (hash_descriptor[prng.u.yarrow.hash]->test && 314 ((err = hash_descriptor[prng.u.yarrow.hash]->test()) != CRYPT_OK)) { 315 return err; 316 } 317 318 return CRYPT_OK; 319 #endif 320 } 321 322 #endif 323 324