1 // SPDX-License-Identifier: BSD-2-Clause
2 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
3  *
4  * LibTomCrypt is a library that provides various cryptographic
5  * algorithms in a highly modular and flexible manner.
6  *
7  * The library is free for all purposes without any express
8  * guarantee it works.
9  */
10 #include "tomcrypt_private.h"
11 
12 #if defined(LTC_MRSA) || (!defined(LTC_NO_MATH) && !defined(LTC_NO_PRNGS))
13 
14 /**
15   @file rand_prime.c
16   Generate a random prime, Tom St Denis
17 */
18 
19 #define USE_BBS 1
20 
rand_prime(void * N,long len,prng_state * prng,int wprng)21 int rand_prime(void *N, long len, prng_state *prng, int wprng)
22 {
23    int            err, res, type;
24    unsigned char *buf;
25 
26    LTC_ARGCHK(N != NULL);
27 
28    /* get type */
29    if (len < 0) {
30       type = USE_BBS;
31       len = -len;
32    } else {
33       type = 0;
34    }
35 
36    /* allow sizes between 2 and 512 bytes for a prime size */
37    if (len < 2 || len > 512) {
38       return CRYPT_INVALID_PRIME_SIZE;
39    }
40 
41    /* valid PRNG? Better be! */
42    if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
43       return err;
44    }
45 
46    /* allocate buffer to work with */
47    buf = XCALLOC(1, len);
48    if (buf == NULL) {
49        return CRYPT_MEM;
50    }
51 
52    do {
53       /* generate value */
54       if (prng_descriptor[wprng]->read(buf, len, prng) != (unsigned long)len) {
55          XFREE(buf);
56          return CRYPT_ERROR_READPRNG;
57       }
58 
59       /* munge bits */
60       buf[0]     |= 0x80 | 0x40;
61       buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00);
62 
63       /* load value */
64       if ((err = mp_read_unsigned_bin(N, buf, len)) != CRYPT_OK) {
65          XFREE(buf);
66          return err;
67       }
68 
69       /* test */
70       if ((err = mp_prime_is_prime(N, LTC_MILLER_RABIN_REPS, &res)) != CRYPT_OK) {
71          XFREE(buf);
72          return err;
73       }
74    } while (res == LTC_MP_NO);
75 
76 #ifdef LTC_CLEAN_STACK
77    zeromem(buf, len);
78 #endif
79 
80    XFREE(buf);
81    return CRYPT_OK;
82 }
83 
84 #endif /* LTC_NO_MATH */
85 
86 
87 /* ref:         $Format:%D$ */
88 /* git commit:  $Format:%H$ */
89 /* commit time: $Format:%ai$ */
90