/ ltc-rand.c
ltc-rand.c
1 /* 2 * Licensed under the Apache License, Version 2.0 (the "License"); 3 * you may not use this file except in compliance with the License. 4 * See the NOTICE file distributed with this work for additional 5 * information regarding copyright ownership. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <stdarg.h> 18 #include <lscore/plugin.h> 19 #include <lscrypto/rand.h> 20 #include <tomcrypt.h> 21 #include <lsplugin/param.h> 22 #include <lsplugin/mkoperator.h> 23 #include "ltc-methods.h" 24 25 #define T(x) LE_status_is_OK(x) 26 27 #define nelems(a) (sizeof(a) / sizeof(a[0])) 28 29 struct ltc_rbg_st { 30 const struct ltc_prng_descriptor *prng; 31 prng_state state; /* libtomcrypt prng state */ 32 int wprng; /* libtomcrypt prng registration number */ 33 34 size_t min_entropy_bits; 35 }; 36 37 static LE_STATUS setup_rbg_data(LSC_rbg_t *rbg) 38 { 39 assert(rbg != NULL); 40 41 const LSplugin_rbg_desc_t *desc = rbg->lsc_dispatch_data; 42 struct ltc_rbg_st **state = (struct ltc_rbg_st **)&rbg->lsc_data; 43 if (*state == NULL) { 44 *state = malloc(sizeof(**state)); 45 memset(*state, 0, sizeof(**state)); 46 (*state)->wprng = -1; 47 48 LE_STATUS sts; 49 int wprng = find_prng(desc->lsp_id); 50 51 if (wprng == -1) 52 wprng = register_prng(desc->lsp_priv_desc); 53 if (wprng < 0) 54 return LE_STS_ERROR; 55 (*state)->prng = desc->lsp_priv_desc; 56 (*state)->wprng = wprng; 57 (*state)->min_entropy_bits = 128; 58 } 59 if (*state == NULL) 60 return LE_STS_FATAL_ERROR; 61 62 assert((*state)->prng == desc->lsp_priv_desc); 63 assert((*state)->wprng >= 0); 64 65 return LE_STS_SUCCESS; 66 } 67 68 static LE_STATUS clean_rbg_data(LSC_rbg_t *rbg) 69 { 70 return LE_STS_SUCCESS; 71 } 72 73 static LE_STATUS start_rbg(LSC_rbg_t *rbg, const char *personalization) 74 { 75 int err; /* libtomcrypt error code */ 76 77 assert(rbg != NULL && rbg->lsc_data != NULL); 78 79 struct ltc_rbg_st *state = rbg->lsc_data; 80 81 err = rng_make_prng(state->min_entropy_bits, state->wprng, &state->state, NULL); 82 if (err != CRYPT_OK) 83 return LE_STS_ERROR; 84 if (personalization != NULL) 85 err = state->prng->add_entropy((unsigned char *)personalization, 86 strlen(personalization), 87 &state->state); 88 if (err != CRYPT_OK) 89 return LE_STS_ERROR; 90 return LE_STS_SUCCESS; 91 } 92 93 static LE_STATUS extract_rbg_output(LSC_rbg_t *rbg, size_t number_of_bits, 94 size_t security_strength, 95 _Bool prediction_resistance, 96 const char *additional_input, 97 unsigned char *out, size_t outsize, 98 size_t *outlen) 99 { 100 int err; /* libtomcrypt error code */ 101 102 assert(rbg != NULL && rbg->lsc_data != NULL); 103 104 struct ltc_rbg_st *state = rbg->lsc_data; 105 size_t number_of_bytes = (number_of_bits + 7) / 8; 106 107 if (number_of_bytes > outsize) 108 return LE_STS_ERROR; 109 110 if (additional_input != NULL) { 111 err = state->prng->add_entropy((unsigned char *)additional_input, 112 strlen(additional_input), 113 &state->state); 114 if (err != CRYPT_OK) 115 return LE_STS_ERROR; 116 } 117 118 size_t n = state->prng->read(out, number_of_bytes, &state->state); 119 *outlen = n; 120 return LE_STS_SUCCESS; 121 } 122 123 static LE_STATUS reseed_rbg(LSC_rbg_t *rbg, const char *additional_input) 124 { 125 return LE_STS_ERROR; 126 } 127 128 static LE_STATUS stop_rbg(LSC_rbg_t *rbg) 129 { 130 int err; /* libtomcrypt error code */ 131 132 assert(rbg != NULL && rbg->lsc_data != NULL); 133 134 struct ltc_rbg_st *state = rbg->lsc_data; 135 136 err = state->prng->done(&state->state); 137 if (err != CRYPT_OK) 138 return LE_STS_ERROR; 139 return LE_STS_SUCCESS; 140 } 141 142 const LSplugin_rbg_desc_t ltc_fortuna_desc = { 143 NULL, "fortuna", &fortuna_desc, NULL, 144 setup_rbg_data, clean_rbg_data, 145 NULL, NULL, NULL, 146 (int[]){ LSC_RBG_TYPE_BASE_COMMANDS(), 147 LSC_NR_start_rbg, 148 LSC_NR_extract_rbg_output, 149 LSC_NR_stop_rbg, 0 }, 150 NULL, /* No get_param_data */ 151 NULL, /* No gettable */ 152 NULL, /* No settable */ 153 NULL, /* No set_entropy_source */ 154 &start_rbg, 155 &extract_rbg_output, 156 NULL, /* No reseed */ 157 &stop_rbg, 158 };