int CipherContext::authEncrypt(State & state, mbedtls_cipher_context_t * context){ Stack * stack = state.stack; if (stack->is<LUA_TSTRING>(1) && stack->is<LUA_TSTRING>(2) && stack->is<LUA_TNUMBER>(3) && stack->is<LUA_TNUMBER>(4)){ const std::string iv = stack->toLString(1); const std::string input = stack->toLString(2); size_t outputSize = stack->to<int>(3); unsigned char * output = new unsigned char[outputSize]; size_t tagSize = stack->to<int>(4); unsigned char * tag = new unsigned char[tagSize]; int result = -1; if (stack->is<LUA_TSTRING>(5)){ const std::string ad = stack->toLString(5); result = mbedtls_cipher_auth_encrypt(context, reinterpret_cast<const unsigned char*>(iv.c_str()), iv.length(), reinterpret_cast<const unsigned char*>(ad.c_str()), ad.length(), reinterpret_cast<const unsigned char*>(input.c_str()), input.length(), output, &outputSize, tag, tagSize ); } else{ result = mbedtls_cipher_auth_encrypt(context, reinterpret_cast<const unsigned char*>(iv.c_str()), iv.length(), nullptr, 0, reinterpret_cast<const unsigned char*>(input.c_str()), input.length(), output, &outputSize, tag, tagSize ); } if (result == 0){ stack->pushLString(std::string(reinterpret_cast<char*>(output), outputSize)); stack->pushLString(std::string(reinterpret_cast<char*>(tag), tagSize)); delete[] output; delete[] tag; return 2; } else{ stack->push<int>(result); return 1; } } return 0; }
static int aead_cipher_encrypt(cipher_ctx_t *cipher_ctx, uint8_t *c, size_t *clen, uint8_t *m, size_t mlen, uint8_t *ad, size_t adlen, uint8_t *n, uint8_t *k) { int err = CRYPTO_OK; unsigned long long long_clen = 0; size_t nlen = cipher_ctx->cipher->nonce_len; size_t tlen = cipher_ctx->cipher->tag_len; switch (cipher_ctx->cipher->method) { case AES256GCM: // Only AES-256-GCM is supported by libsodium. if (cipher_ctx->aes256gcm_ctx != NULL) { // Use it if availble err = crypto_aead_aes256gcm_encrypt_afternm(c, &long_clen, m, mlen, ad, adlen, NULL, n, (const aes256gcm_ctx *)cipher_ctx->aes256gcm_ctx); *clen = (size_t)long_clen; // it's safe to cast 64bit to 32bit length here break; } // Otherwise, just use the mbedTLS one with crappy AES-NI. case AES192GCM: case AES128GCM: err = mbedtls_cipher_auth_encrypt(cipher_ctx->evp, n, nlen, ad, adlen, m, mlen, c, clen, c + mlen, tlen); *clen += tlen; break; case CHACHA20POLY1305IETF: err = crypto_aead_chacha20poly1305_ietf_encrypt(c, &long_clen, m, mlen, ad, adlen, NULL, n, k); *clen = (size_t)long_clen; break; #ifdef FS_HAVE_XCHACHA20IETF case XCHACHA20POLY1305IETF: err = crypto_aead_xchacha20poly1305_ietf_encrypt(c, &long_clen, m, mlen, ad, adlen, NULL, n, k); *clen = (size_t)long_clen; break; #endif default: return CRYPTO_ERROR; } return err; }
static int aead_cipher_encrypt(cipher_ctx_t *cipher_ctx, uint8_t *c, size_t *clen, uint8_t *m, size_t mlen, uint8_t *ad, size_t adlen, uint8_t *n, uint8_t *k) { int err = CRYPTO_OK; unsigned long long long_clen = 0; size_t nlen = cipher_ctx->cipher->nonce_len; size_t tlen = cipher_ctx->cipher->tag_len; switch (cipher_ctx->cipher->method) { case AES128GCM: case AES192GCM: case AES256GCM: err = mbedtls_cipher_auth_encrypt(cipher_ctx->evp, n, nlen, ad, adlen, m, mlen, c, clen, c + mlen, tlen); *clen += tlen; break; case CHACHA20POLY1305IETF: err = crypto_aead_chacha20poly1305_ietf_encrypt(c, &long_clen, m, mlen, ad, adlen, NULL, n, k); *clen = (size_t)long_clen; break; #ifdef FS_HAVE_XCHACHA20IETF case XCHACHA20POLY1305IETF: err = crypto_aead_xchacha20poly1305_ietf_encrypt(c, &long_clen, m, mlen, ad, adlen, NULL, n, k); *clen = (size_t)long_clen; break; #endif default: return CRYPTO_ERROR; } return err; }