/ ltc-sym-keys.c
ltc-sym-keys.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 <stdbool.h> 19 #include <lscore/plugin.h> 20 #include <tomcrypt.h> 21 #include <lsplugin/mkobject.h> 22 #include <lsplugin/mkoperator.h> 23 #include <lsplugin/param.h> 24 #include "ltc-methods.h" 25 #include "ltc-sym-keys.h" 26 27 #define T(x) LE_status_is_OK(x) 28 29 #define nelems(a) (sizeof(a) / sizeof(a[0])) 30 31 /* 32 * Key data support functions. The key data they manipulate, 33 * struct ltc_symkey_st, is defined in ltc-sym-keys.h. 34 */ 35 /* 36 * The functions scrub_symkey(), new_symkey() and 37 * clean_symkey() are defined further down. 38 */ 39 static LE_STATUS scrub_symkey_data(LSC_key_t *obj); 40 static LE_STATUS new_symkey_data(LSC_key_t *obj, const void *desc); 41 42 /* Key constructor operation with support functions */ 43 44 struct ltc_symkey_constructor_st { 45 LSC_key_t *key; 46 47 /* Operational parameters */ 48 49 /* Key bits */ 50 unsigned char *key_bits; 51 size_t key_bits_len; /* Measured in bits */ 52 53 /* 54 * The parameter descriptions. 55 * They need to be dynamic, because the key sizes depend on the algorithm. 56 */ 57 LSC_param_desc_t gettable_params[2]; 58 LSC_param_desc_t settable_params[2]; 59 60 /* True when they've been cached in the key itself */ 61 _Bool key_bits_cached; 62 }; 63 64 static LE_STATUS compute_desc_keysizes(struct ltc_symkey_constructor_st *c, 65 LSC_param_desc_t *desc) 66 { 67 assert(c != NULL && desc != NULL); 68 69 struct ltc_symkey_st *k = (c != NULL) ? c->key->lsc_data : NULL; 70 71 unsigned int kb = 65536; /* We start with something absurdly large */ 72 unsigned int previous_kb = kb; /* To keep track of stepping */ 73 off_t start; /* Where does the series of sizes start? */ 74 off_t end; /* Where does the series of sizes start? */ 75 size_t d_elems_sz = nelems(desc->p_data.d_elems); 76 size_t factor = desc->p_data.d_type == LSC_DT_bit_string ? 8 : 1; 77 size_t step = 0; 78 int ltc_err; 79 80 start = end = d_elems_sz - 1; 81 while (start > 0) { 82 while ((ltc_err = k->desc->keysize(&kb)) == CRYPT_OK 83 && step == previous_kb - kb) { 84 desc->p_data.d_elems[start].min = kb * factor; 85 previous_kb = kb--; 86 } 87 if (ltc_err != CRYPT_OK) 88 break; 89 90 previous_kb = kb--; 91 start--; 92 if (k->desc->keysize(&kb) == CRYPT_OK) { 93 desc->p_data.d_elems[start].max = previous_kb * factor; 94 desc->p_data.d_elems[start].min = kb * factor; 95 step = previous_kb - kb; 96 desc->p_data.d_elems[start].step = step * factor; 97 previous_kb = kb--; 98 } else { 99 desc->p_data.d_elems[start].max = previous_kb * factor; 100 desc->p_data.d_elems[start].min = previous_kb * factor; 101 desc->p_data.d_elems[start].step = 0; 102 break; 103 } 104 } 105 106 /* No sizes at all? That's wrong! */ 107 if (start == d_elems_sz - 1) 108 return LE_STS_ERROR; 109 110 /* Now that we figured them out, adjust the array if needed */ 111 if (start != 0) { 112 for (end = 0; start < d_elems_sz - 1; start++, end++) 113 desc->p_data.d_elems[end] = desc->p_data.d_elems[start]; 114 if (start != d_elems_sz - 1) 115 return LE_STS_ERROR; 116 } 117 118 /* Make sure to terminate */ 119 desc->p_data.d_elems[end].min = desc->p_data.d_elems[end].max = 0; 120 121 return LE_STS_SUCCESS; 122 } 123 124 static LSplugin_param_functions_t symkey_bits_fns = { 125 offsetof(struct ltc_symkey_constructor_st, key_bits), 126 offsetof(struct ltc_symkey_constructor_st, key_bits_len), 127 0, false, 128 LSplugin_set_bitstring_param, LSplugin_get_bitstring_param 129 }; 130 #define SYM_CIPHER_I_key_bits 1 131 #define SYM_CIPHER_P_key_bits \ 132 { "key", SYM_CIPHER_I_key_bits, \ 133 { LSC_DT_bit_string, { { 0, 0 }, }, \ 134 .d_auxilliary = { 0 }, }, \ 135 &symkey_bits_fns } 136 137 static LE_STATUS scrub_symkey_constructor_data(LSC_key_constructor_t *op) 138 { 139 if (op == NULL || op->lsc_data == NULL) 140 return LE_STS_SUCCESS; 141 142 struct ltc_symkey_constructor_st *g = op->lsc_data; 143 144 memset(g, 0, sizeof(*g)); 145 return LE_STS_SUCCESS; 146 } 147 148 static LE_STATUS new_symkey_constructor_data(LSC_key_constructor_t *op) 149 { 150 LE_STATUS sts; 151 152 if (op == NULL) 153 return LE_STS_ERROR; 154 155 struct ltc_symkey_constructor_st **g 156 = (struct ltc_symkey_constructor_st **)&op->lsc_data; 157 158 if (*g == NULL && (*g = malloc(sizeof(**g))) != NULL) 159 memset(*g, 0, sizeof(**g)); 160 if (*g == NULL) 161 return LE_STS_FATAL_ERROR; 162 return LE_STS_SUCCESS; 163 } 164 165 static LE_STATUS clean_symkey_constructor_data(LSC_key_constructor_t *op) 166 { 167 LE_STATUS sts; 168 169 if (op == NULL || op->lsc_data == NULL) 170 return LE_STS_SUCCESS; 171 if (T(sts = scrub_symkey_constructor_data(op))) { 172 free(op->lsc_data); 173 op->lsc_data = NULL; 174 } 175 return sts; 176 } 177 178 static LE_STATUS set_symkey_constructor(LSC_key_t *key, 179 LSC_key_constructor_t *op) 180 { 181 struct ltc_symkey_st *k = key->lsc_data; 182 183 k->constructor = op; 184 return LE_STS_SUCCESS; 185 } 186 187 static LE_STATUS set_constructor_symkey(LSC_key_constructor_t *op, 188 LSC_key_t *key) 189 { 190 LE_STATUS sts; 191 192 if (LE_status_is_OK(sts = new_symkey_constructor_data(op))) { 193 struct ltc_symkey_constructor_st *c = op->lsc_data; 194 195 c->key = key; 196 197 c->gettable_params[0] = (LSC_param_desc_t) SYM_CIPHER_P_key_bits; 198 if (!LE_status_is_OK(sts = compute_desc_keysizes(c, &c->gettable_params[0]))) 199 return sts; 200 c->gettable_params[1] = (LSC_param_desc_t) { NULL, }; 201 202 c->settable_params[0] = (LSC_param_desc_t) SYM_CIPHER_P_key_bits; 203 if (!LE_status_is_OK(sts = compute_desc_keysizes(c, &c->settable_params[0]))) 204 return sts; 205 c->settable_params[1] = (LSC_param_desc_t) { NULL, }; 206 } 207 return sts; 208 } 209 210 static LE_STATUS get_constructor_symkey(LSC_key_constructor_t *op, 211 LSC_key_t **key) 212 { 213 struct ltc_symkey_constructor_st *c = op->lsc_data; 214 215 *key = c->key; 216 return LE_STS_SUCCESS; 217 } 218 219 static LE_STATUS get_construction_param_data(LSC_key_constructor_t *op, void **data) 220 { 221 *data = op->lsc_data; 222 return LE_STS_SUCCESS; 223 } 224 225 static LE_STATUS 226 get_gettable_construction_param_desc(LSC_key_constructor_t *op, 227 const LSC_param_desc_t **param_desc) 228 { 229 assert(op != NULL); 230 assert(param_desc != NULL); 231 232 if (op->lsc_data == NULL) { 233 static const LSC_param_desc_t pd[] = { 234 SYM_CIPHER_P_key_bits, 235 { NULL, } 236 }; 237 *param_desc = pd; 238 } else { 239 struct ltc_symkey_constructor_st *c = op->lsc_data; 240 *param_desc = c->gettable_params; 241 } 242 return LE_STS_SUCCESS; 243 } 244 245 static LE_STATUS 246 get_settable_construction_param_desc(LSC_key_constructor_t *op, 247 const LSC_param_desc_t **param_desc) 248 { 249 assert(op != NULL); 250 assert(param_desc != NULL); 251 252 if (op->lsc_data == NULL) { 253 static const LSC_param_desc_t pd[] = { 254 SYM_CIPHER_P_key_bits, 255 { NULL, } 256 }; 257 *param_desc = pd; 258 } else { 259 struct ltc_symkey_constructor_st *c = op->lsc_data; 260 *param_desc = c->settable_params; 261 } 262 return LE_STS_SUCCESS; 263 } 264 265 LE_STATUS construct_symkey_data(LSC_key_constructor_t *op) 266 { 267 LE_STATUS sts; 268 struct ltc_symkey_constructor_st *c = op->lsc_data; 269 LSC_key_t *key = c != NULL ? c->key : NULL; 270 struct ltc_symkey_st *k = (key != NULL) ? key->lsc_data : NULL; 271 272 if (T(sts = scrub_symkey_data(key))) { 273 int err = k->desc->setup(c->key_bits, c->key_bits_len / 8, 0, &k->key); 274 sts = (err == CRYPT_OK) ? LE_STS_SUCCESS : LE_STS_ERROR; 275 if (T(sts)) { 276 /* Cache the key bits in the key itself too, to support extraction */ 277 k->key_bits = c->key_bits; 278 k->key_bits_len = c->key_bits_len; 279 c->key_bits_cached = true; 280 } 281 } 282 return sts; 283 } 284 285 /* local symkey constructor descriptor, used in |ltc_{name}_desc| below */ 286 static LSplugin_key_constructor_desc_t ltc_symkey_constructor_desc = { 287 NULL, NULL, NULL, NULL, /* lsp_docstring, lsp_id, lsp_priv_desc, lsp_key_id */ 288 new_symkey_constructor_data, clean_symkey_constructor_data, 289 set_symkey_constructor, set_constructor_symkey, get_constructor_symkey, 290 (int[]){ LSC_KEY_TYPE_CONSTRUCTOR_COMMANDS(), 291 LSC_NR_get_settable_key_construction_param_desc, 292 LSC_NR_set_key_construction_param, 293 LSC_NR_get_gettable_key_construction_param_desc, 294 LSC_NR_get_key_construction_param, 295 LSC_NR_construct_key, 0 }, 296 get_construction_param_data, 297 get_gettable_construction_param_desc, /* gettable */ 298 get_settable_construction_param_desc, /* settable */ 299 construct_symkey_data 300 }; 301 302 /* Key associated operations (they all use the same libtomcrypt function) */ 303 304 LE_STATUS get_symkey_unit_size(LSC_key_t *key, size_t *size) 305 { 306 struct ltc_symkey_st *k = key->lsc_data; 307 308 *size = k->desc->block_length; 309 return LE_STS_SUCCESS; 310 } 311 312 LE_STATUS get_symkey_input_size(LSC_key_t *key, size_t *size) 313 { 314 return get_symkey_unit_size(key, size); 315 } 316 317 LE_STATUS get_symkey_output_size(LSC_key_t *key, size_t *size) 318 { 319 return get_symkey_unit_size(key, size); 320 } 321 322 #define IMPL_ASSOCIATED_OP_FUNCTIONS(T,N,F) \ 323 static LE_STATUS set_symkey_##T(LSC_key_t *key, LSC_##T##_t *op) \ 324 { \ 325 struct ltc_symkey_st *k = key->lsc_data; \ 326 \ 327 k->T = op; \ 328 return LE_STS_SUCCESS; \ 329 } \ 330 static LE_STATUS set_##T##_symkey(LSC_##T##_t *op, LSC_key_t *key) \ 331 { \ 332 op->lsc_data = key; \ 333 return LE_STS_SUCCESS; \ 334 } \ 335 static LE_STATUS get_##T##_symkey(LSC_##T##_t *op, LSC_key_t **key) \ 336 { \ 337 *key = op->lsc_data; \ 338 return LE_STS_SUCCESS; \ 339 } \ 340 LE_STATUS perform_symkey_##N##_once(LSC_##T##_t *op, \ 341 const unsigned char *in, \ 342 size_t inlen, \ 343 unsigned char *out, \ 344 size_t outsize, \ 345 size_t *outlen) \ 346 { \ 347 LE_STATUS sts; \ 348 LSC_key_t *key = NULL; \ 349 \ 350 if (!LE_status_is_OK(get_##T##_symkey(op, &key))) \ 351 return sts; \ 352 \ 353 struct ltc_symkey_st *k = key->lsc_data; \ 354 \ 355 if (inlen != k->desc->block_length \ 356 || outsize < k->desc->block_length) \ 357 return LE_STS_ERROR; \ 358 \ 359 int err = k->desc->F(in, out, &k->key); \ 360 sts = (err == CRYPT_OK) ? LE_STS_SUCCESS : LE_STS_ERROR; \ 361 \ 362 if (LE_status_is_OK(sts)) \ 363 *outlen = inlen; \ 364 return sts; \ 365 } 366 #define IMPL_PRIMITIVE_SIZE_FUNCTION(T,N,K) \ 367 static LE_STATUS get_symkey_##N##_##K##_size(LSC_##T##_t *op, \ 368 size_t *size) \ 369 { \ 370 LE_STATUS sts; \ 371 LSC_key_t *key = NULL; \ 372 if (!LE_status_is_OK(sts = get_##T##_symkey(op, &key))) \ 373 return sts; \ 374 return get_symkey_##K##_size(key, size); \ 375 } 376 377 IMPL_ASSOCIATED_OP_FUNCTIONS(encryptor,encryption,ecb_encrypt); 378 IMPL_PRIMITIVE_SIZE_FUNCTION(encryptor,encryption,unit); 379 IMPL_PRIMITIVE_SIZE_FUNCTION(encryptor,encryption,input); 380 IMPL_PRIMITIVE_SIZE_FUNCTION(encryptor,encryption,output); 381 #define SPEC_SYMKEY_encryptor_COMMANDS() \ 382 LSC_ENCRYPTOR_TYPE_BASE_COMMANDS(), LSC_ENCRYPTOR_SIZE_COMMANDS(), \ 383 LSC_NR_perform_encryption_once 384 #define SPEC_SYMKEY_encryptor_FUNCTIONS() \ 385 get_symkey_encryption_unit_size, get_symkey_encryption_input_size, \ 386 get_symkey_encryption_output_size, perform_symkey_encryption_once 387 388 IMPL_ASSOCIATED_OP_FUNCTIONS(decryptor,decryption,ecb_decrypt); 389 IMPL_PRIMITIVE_SIZE_FUNCTION(decryptor,decryption,unit); 390 IMPL_PRIMITIVE_SIZE_FUNCTION(decryptor,decryption,input); 391 IMPL_PRIMITIVE_SIZE_FUNCTION(decryptor,decryption,output); 392 #define SPEC_SYMKEY_decryptor_COMMANDS() \ 393 LSC_DECRYPTOR_TYPE_BASE_COMMANDS(), LSC_DECRYPTOR_SIZE_COMMANDS(), \ 394 LSC_NR_perform_decryption_once 395 #define SPEC_SYMKEY_decryptor_FUNCTIONS() \ 396 get_symkey_decryption_unit_size, get_symkey_decryption_input_size, \ 397 get_symkey_decryption_output_size, perform_symkey_decryption_once 398 399 #define IMPL_ASSOCIATED_OP(T) \ 400 LSplugin_##T##_desc_t ltc_symkey_##T##_desc = { \ 401 NULL, NULL, NULL, NULL, /* lsp_docstring, lsp_id, lsp_priv_desc, lsp_key_id */ \ 402 NULL, NULL, set_symkey_##T, set_##T##_symkey, get_##T##_symkey, \ 403 (int[]){ SPEC_SYMKEY_##T##_COMMANDS() }, \ 404 NULL, NULL, NULL, \ 405 SPEC_SYMKEY_##T##_FUNCTIONS() \ 406 } 407 408 IMPL_ASSOCIATED_OP(encryptor); 409 IMPL_ASSOCIATED_OP(decryptor); 410 411 /* Main object functions */ 412 413 static LE_STATUS scrub_symkey_data(LSC_key_t *key) 414 { 415 if (key == NULL || key->lsc_data == NULL) 416 return LE_STS_SUCCESS; 417 418 struct ltc_symkey_st *k = key->lsc_data; 419 420 k->desc->done(&k->key); 421 /* DO NOTE that we aren't scrubbing the cached associated operations */ 422 return LE_STS_SUCCESS; 423 } 424 425 static LE_STATUS new_symkey_data(LSC_key_t *key, const void *desc) 426 { 427 LE_STATUS sts; 428 429 if (key == NULL) 430 return LE_STS_ERROR; 431 struct ltc_symkey_st **k = (struct ltc_symkey_st **)&key->lsc_data; 432 433 if (*k == NULL && (*k = malloc(sizeof(**k))) != NULL) { 434 memset(*k, 0, sizeof(**k)); 435 (*k)->desc = desc; 436 } 437 if (*k == NULL) 438 return LE_STS_FATAL_ERROR; 439 return LE_STS_SUCCESS; 440 } 441 442 static LE_STATUS clean_symkey_data(LSC_key_t *key) 443 { 444 LE_STATUS sts; 445 446 if (key == NULL || key->lsc_data == NULL) 447 return LE_STS_SUCCESS; 448 if (T(sts = scrub_symkey_data(key))) { 449 struct ltc_symkey_st *k = key->lsc_data; 450 /* 451 * The constructor, encryptor and decryptor are cached, so they don't 452 * provide a destroy function in the operation object, which means 453 * that the LSC_free_key_{operation}() calls end up doing nothing. 454 * Therefore, we must destroy them now, using their destroy functions 455 * (which do exist) directly. 456 */ 457 LSplugin_destroy_key_constructor(k->constructor); 458 LSplugin_destroy_encryptor(k->encryptor); 459 LSplugin_destroy_decryptor(k->decryptor); 460 free(k); 461 key->lsc_data = NULL; 462 } 463 return sts; 464 } 465 466 static LE_STATUS get_symkey_size(LSC_key_t *key, size_t *keysize) 467 { 468 struct ltc_symkey_st *k = key->lsc_data; 469 470 if (k->key_bits == NULL) 471 return LE_STS_ERROR; 472 *keysize = k->key_bits_len; 473 return LE_STS_SUCCESS; 474 } 475 476 #define IMPL_aes_NAME() "aes" 477 #define IMPL_des3_NAME() "3des" 478 #define IMPL_blowfish_NAME() "blowfish" 479 #define IMPL_twofish_NAME() "twofish" 480 #define IMPL_cast5_NAME() "cast5" 481 #define IMPL_kseed_NAME() "seed" 482 #define IMPL_camellia_NAME() "camellia" 483 #define IMPL_CIPHER_KEY(N, propdef) \ 484 const LSplugin_key_desc_t ltc_##N##_desc = { \ 485 NULL, IMPL_##N##_NAME(), &N##_desc, \ 486 new_symkey_data, clean_symkey_data, \ 487 (int[]){ LSC_KEY_TYPE_BASE_COMMANDS(), \ 488 LSC_NR_get_key_size, \ 489 LSC_NR_get_key_constructor, \ 490 LSC_NR_get_associated_encryptor, \ 491 LSC_NR_get_associated_decryptor, 0 }, \ 492 get_symkey_size, \ 493 NULL, \ 494 <c_symkey_constructor_desc, \ 495 NULL, \ 496 <c_symkey_encryptor_desc, \ 497 <c_symkey_decryptor_desc, \ 498 } 499 IMPL_CIPHER_KEY(aes, NULL); 500 IMPL_CIPHER_KEY(des3, NULL); 501 IMPL_CIPHER_KEY(blowfish, NULL); 502 IMPL_CIPHER_KEY(twofish, NULL); 503 IMPL_CIPHER_KEY(cast5, NULL); 504 IMPL_CIPHER_KEY(kseed, NULL); 505 IMPL_CIPHER_KEY(camellia, NULL);