1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4 
5 /**
6   @file rsa_key.c
7   Free an RSA key, Tom St Denis
8   Basic operations on an RSA key, Steffen Jaeckel
9 */
10 
11 #ifdef LTC_MRSA
12 #include <stdarg.h>
13 
s_mpi_shrink_multi(void ** a,...)14 static void s_mpi_shrink_multi(void **a, ...)
15 {
16    void **cur;
17    unsigned n;
18    int err;
19    va_list args;
20    void *tmp[10] = { 0 };
21    void **arg[10] = { 0 };
22 
23    /* We re-allocate in the order that we received the varargs */
24    n = 0;
25    err = CRYPT_ERROR;
26    cur = a;
27    va_start(args, a);
28    while (cur != NULL) {
29       if (n >= sizeof(tmp)/sizeof(tmp[0])) {
30          goto out;
31       }
32       if (*cur != NULL) {
33          arg[n] = cur;
34          if ((err = mp_init_copy(&tmp[n], *arg[n])) != CRYPT_OK) {
35             goto out;
36          }
37          n++;
38       }
39       cur = va_arg(args, void**);
40    }
41    va_end(args);
42 
43    /* but we clear the old values in the reverse order */
44    while (n != 0 && arg[--n] != NULL) {
45       mp_clear(*arg[n]);
46       *arg[n] = tmp[n];
47    }
48 out:
49    va_end(args);
50    /* clean-up after an error
51     * or after this was called with too many args
52     */
53    if ((err != CRYPT_OK) ||
54          (n >= sizeof(tmp)/sizeof(tmp[0]))) {
55       for (n = 0; n < sizeof(tmp)/sizeof(tmp[0]); ++n) {
56          if (tmp[n] != NULL) {
57             mp_clear(tmp[n]);
58          }
59       }
60    }
61 }
62 
63 /**
64   This shrinks the allocated memory of a RSA key
65 
66      It will use up some more memory temporarily,
67      but then it will free-up the entire sequence that
68      was once allocated when the key was created/populated.
69 
70      This only works with libtommath >= 1.2.0 in earlier versions
71      it has the inverse effect due to the way it worked internally.
72      Also works for GNU MP, tomsfastmath naturally shows no effect.
73 
74   @param key   The RSA key to shrink
75 */
rsa_shrink_key(rsa_key * key)76 void rsa_shrink_key(rsa_key *key)
77 {
78    LTC_ARGCHKVD(key != NULL);
79    s_mpi_shrink_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL);
80 }
81 
82 /**
83   Init an RSA key
84   @param key   The RSA key to free
85   @return CRYPT_OK if successful
86 */
rsa_init(rsa_key * key)87 int rsa_init(rsa_key *key)
88 {
89    LTC_ARGCHK(key != NULL);
90    return mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, LTC_NULL);
91 }
92 
93 /**
94   Free an RSA key from memory
95   @param key   The RSA key to free
96 */
rsa_free(rsa_key * key)97 void rsa_free(rsa_key *key)
98 {
99    LTC_ARGCHKVD(key != NULL);
100    mp_cleanup_multi(&key->q, &key->p, &key->qP, &key->dP, &key->dQ, &key->N, &key->d, &key->e, LTC_NULL);
101 }
102 
103 #endif
104