Comparison

util-src/crypto.c @ 12837:d3ae47d8a7a7

util.crypto: Add support for AES-256-CTR This is required by PASETO v3.local
author Matthew Wild <mwild1@gmail.com>
date Fri, 13 Jan 2023 14:34:10 +0000
parent 12735:445f7bd6ffc4
child 12876:0ed24f48b6a6
comparison
equal deleted inserted replaced
12836:dbe9781fd278 12837:d3ae47d8a7a7
283 283
284 static int Led25519_verify(lua_State *L) { 284 static int Led25519_verify(lua_State *L) {
285 return base_evp_verify(L, NID_ED25519, NULL); 285 return base_evp_verify(L, NID_ED25519, NULL);
286 } 286 }
287 287
288 /* gcm_encrypt(key, iv, plaintext) */ 288 /* encrypt(key, iv, plaintext) */
289 static int Laes_gcm_encrypt(lua_State *L, const EVP_CIPHER *cipher, const unsigned char expected_key_len) { 289 static int Levp_encrypt(lua_State *L, const EVP_CIPHER *cipher, const unsigned char expected_key_len, const unsigned char expected_iv_len, const size_t tag_len) {
290 EVP_CIPHER_CTX *ctx; 290 EVP_CIPHER_CTX *ctx;
291 luaL_Buffer ciphertext_buffer; 291 luaL_Buffer ciphertext_buffer;
292 292
293 size_t key_len, iv_len, plaintext_len; 293 size_t key_len, iv_len, plaintext_len;
294 int ciphertext_len, final_len; 294 int ciphertext_len, final_len;
298 const unsigned char *plaintext = (unsigned char*)luaL_checklstring(L, 3, &plaintext_len); 298 const unsigned char *plaintext = (unsigned char*)luaL_checklstring(L, 3, &plaintext_len);
299 299
300 if(key_len != expected_key_len) { 300 if(key_len != expected_key_len) {
301 return luaL_error(L, "key must be %d bytes", expected_key_len); 301 return luaL_error(L, "key must be %d bytes", expected_key_len);
302 } 302 }
303 luaL_argcheck(L, iv_len == 12, 2, "iv must be 12 bytes"); 303 if(iv_len != expected_iv_len) {
304 return luaL_error(L, "iv must be %d bytes", expected_iv_len);
305 }
304 if(lua_gettop(L) > 3) { 306 if(lua_gettop(L) > 3) {
305 return luaL_error(L, "Expected 3 arguments, got %d", lua_gettop(L)); 307 return luaL_error(L, "Expected 3 arguments, got %d", lua_gettop(L));
306 } 308 }
307 309
308 // Create and initialise the context 310 // Create and initialise the context
317 if(1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) { 319 if(1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) {
318 return luaL_error(L, "Error while initializing key/iv"); 320 return luaL_error(L, "Error while initializing key/iv");
319 } 321 }
320 322
321 luaL_buffinit(L, &ciphertext_buffer); 323 luaL_buffinit(L, &ciphertext_buffer);
322 unsigned char *ciphertext = (unsigned char*)luaL_prepbuffsize(&ciphertext_buffer, plaintext_len+16); 324 unsigned char *ciphertext = (unsigned char*)luaL_prepbuffsize(&ciphertext_buffer, plaintext_len+tag_len);
323 325
324 if(1 != EVP_EncryptUpdate(ctx, ciphertext, &ciphertext_len, plaintext, plaintext_len)) { 326 if(1 != EVP_EncryptUpdate(ctx, ciphertext, &ciphertext_len, plaintext, plaintext_len)) {
325 return luaL_error(L, "Error while encrypting data"); 327 return luaL_error(L, "Error while encrypting data");
326 } 328 }
327 329
334 } 336 }
335 if(final_len != 0) { 337 if(final_len != 0) {
336 return luaL_error(L, "Non-zero final data"); 338 return luaL_error(L, "Non-zero final data");
337 } 339 }
338 340
339 /* Get the tag */ 341 if(tag_len > 0) {
340 if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, ciphertext + ciphertext_len)) { 342 /* Get the tag */
341 return luaL_error(L, "Unable to read AEAD tag of encrypted data"); 343 if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, tag_len, ciphertext + ciphertext_len)) {
342 } 344 return luaL_error(L, "Unable to read AEAD tag of encrypted data");
343 345 }
344 luaL_addsize(&ciphertext_buffer, ciphertext_len + 16); 346 /* Append tag */
347 luaL_addsize(&ciphertext_buffer, ciphertext_len + tag_len);
348 } else {
349 luaL_addsize(&ciphertext_buffer, ciphertext_len);
350 }
345 luaL_pushresult(&ciphertext_buffer); 351 luaL_pushresult(&ciphertext_buffer);
346 352
347 return 1; 353 return 1;
348 } 354 }
349 355
350 static int Laes_128_gcm_encrypt(lua_State *L) { 356 static int Laes_128_gcm_encrypt(lua_State *L) {
351 return Laes_gcm_encrypt(L, EVP_aes_128_gcm(), 16); 357 return Levp_encrypt(L, EVP_aes_128_gcm(), 16, 12, 16);
352 } 358 }
353 359
354 static int Laes_256_gcm_encrypt(lua_State *L) { 360 static int Laes_256_gcm_encrypt(lua_State *L) {
355 return Laes_gcm_encrypt(L, EVP_aes_256_gcm(), 32); 361 return Levp_encrypt(L, EVP_aes_256_gcm(), 32, 12, 16);
356 } 362 }
357 363
358 /* gcm_decrypt(key, iv, ciphertext) */ 364 static int Laes_256_ctr_encrypt(lua_State *L) {
359 static int Laes_gcm_decrypt(lua_State *L, const EVP_CIPHER *cipher, const unsigned char expected_key_len) { 365 return Levp_encrypt(L, EVP_aes_256_ctr(), 32, 16, 0);
366 }
367
368 /* decrypt(key, iv, ciphertext) */
369 static int Levp_decrypt(lua_State *L, const EVP_CIPHER *cipher, const unsigned char expected_key_len, const unsigned char expected_iv_len, const size_t tag_len) {
360 EVP_CIPHER_CTX *ctx; 370 EVP_CIPHER_CTX *ctx;
361 luaL_Buffer plaintext_buffer; 371 luaL_Buffer plaintext_buffer;
362 372
363 size_t key_len, iv_len, ciphertext_len; 373 size_t key_len, iv_len, ciphertext_len;
364 int plaintext_len, final_len; 374 int plaintext_len, final_len;
368 const unsigned char *ciphertext = (unsigned char*)luaL_checklstring(L, 3, &ciphertext_len); 378 const unsigned char *ciphertext = (unsigned char*)luaL_checklstring(L, 3, &ciphertext_len);
369 379
370 if(key_len != expected_key_len) { 380 if(key_len != expected_key_len) {
371 return luaL_error(L, "key must be %d bytes", expected_key_len); 381 return luaL_error(L, "key must be %d bytes", expected_key_len);
372 } 382 }
373 luaL_argcheck(L, iv_len == 12, 2, "iv must be 12 bytes"); 383 if(iv_len != expected_iv_len) {
374 luaL_argcheck(L, ciphertext_len > 16, 3, "ciphertext must be at least 16 bytes (including tag)"); 384 return luaL_error(L, "iv must be %d bytes", expected_iv_len);
385 }
386 if(ciphertext_len <= tag_len) {
387 return luaL_error(L, "ciphertext must be at least %d bytes (including tag)", tag_len);
388 }
375 if(lua_gettop(L) > 3) { 389 if(lua_gettop(L) > 3) {
376 return luaL_error(L, "Expected 3 arguments, got %d", lua_gettop(L)); 390 return luaL_error(L, "Expected 3 arguments, got %d", lua_gettop(L));
377 } 391 }
378 392
379 /* Create and initialise the context */ 393 /* Create and initialise the context */
394 408
395 /* 409 /*
396 * Provide the message to be decrypted, and obtain the plaintext output. 410 * Provide the message to be decrypted, and obtain the plaintext output.
397 * EVP_DecryptUpdate can be called multiple times if necessary 411 * EVP_DecryptUpdate can be called multiple times if necessary
398 */ 412 */
399 if(!EVP_DecryptUpdate(ctx, plaintext, &plaintext_len, ciphertext, ciphertext_len-16)) { 413 if(!EVP_DecryptUpdate(ctx, plaintext, &plaintext_len, ciphertext, ciphertext_len-tag_len)) {
400 return luaL_error(L, "Error while decrypting data"); 414 return luaL_error(L, "Error while decrypting data");
401 } 415 }
402 416
403 /* Set expected tag value. Works in OpenSSL 1.0.1d and later */ 417 if(tag_len > 0) {
404 if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, (unsigned char*)ciphertext + (ciphertext_len-16))) { 418 /* Set expected tag value. Works in OpenSSL 1.0.1d and later */
405 return luaL_error(L, "Error while processing authentication tag"); 419 if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag_len, (unsigned char*)ciphertext + (ciphertext_len-tag_len))) {
420 return luaL_error(L, "Error while processing authentication tag");
421 }
406 } 422 }
407 423
408 /* 424 /*
409 * Finalise the decryption. A positive return value indicates success, 425 * Finalise the decryption. A positive return value indicates success,
410 * anything else is a failure - the plaintext is not trustworthy. 426 * anything else is a failure - the plaintext is not trustworthy.
422 luaL_pushresult(&plaintext_buffer); 438 luaL_pushresult(&plaintext_buffer);
423 return 1; 439 return 1;
424 } 440 }
425 441
426 static int Laes_128_gcm_decrypt(lua_State *L) { 442 static int Laes_128_gcm_decrypt(lua_State *L) {
427 return Laes_gcm_decrypt(L, EVP_aes_128_gcm(), 16); 443 return Levp_decrypt(L, EVP_aes_128_gcm(), 16, 12, 16);
428 } 444 }
429 445
430 static int Laes_256_gcm_decrypt(lua_State *L) { 446 static int Laes_256_gcm_decrypt(lua_State *L) {
431 return Laes_gcm_decrypt(L, EVP_aes_256_gcm(), 32); 447 return Levp_decrypt(L, EVP_aes_256_gcm(), 32, 12, 16);
448 }
449
450 static int Laes_256_ctr_decrypt(lua_State *L) {
451 return Levp_decrypt(L, EVP_aes_256_ctr(), 32, 16, 0);
432 } 452 }
433 453
434 /* r, s = parse_ecdsa_sig(sig_der) */ 454 /* r, s = parse_ecdsa_sig(sig_der) */
435 static int Lparse_ecdsa_signature(lua_State *L) { 455 static int Lparse_ecdsa_signature(lua_State *L) {
436 ECDSA_SIG *sig; 456 ECDSA_SIG *sig;
545 { "aes_128_gcm_encrypt", Laes_128_gcm_encrypt }, 565 { "aes_128_gcm_encrypt", Laes_128_gcm_encrypt },
546 { "aes_128_gcm_decrypt", Laes_128_gcm_decrypt }, 566 { "aes_128_gcm_decrypt", Laes_128_gcm_decrypt },
547 { "aes_256_gcm_encrypt", Laes_256_gcm_encrypt }, 567 { "aes_256_gcm_encrypt", Laes_256_gcm_encrypt },
548 { "aes_256_gcm_decrypt", Laes_256_gcm_decrypt }, 568 { "aes_256_gcm_decrypt", Laes_256_gcm_decrypt },
549 569
570 { "aes_256_ctr_encrypt", Laes_256_ctr_encrypt },
571 { "aes_256_ctr_decrypt", Laes_256_ctr_decrypt },
572
550 { "generate_ed25519_keypair", Lgenerate_ed25519_keypair }, 573 { "generate_ed25519_keypair", Lgenerate_ed25519_keypair },
551 574
552 { "import_private_pem", Limport_private_pem }, 575 { "import_private_pem", Limport_private_pem },
553 { "import_public_pem", Limport_public_pem }, 576 { "import_public_pem", Limport_public_pem },
554 577