int CipherContext::authDecrypt(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_TSTRING>(3) && stack->is<LUA_TNUMBER>(4)){ const std::string iv = stack->toLString(1); const std::string input = stack->toLString(2); const std::string tag = stack->toLString(3); size_t outputSize = stack->to<int>(4); unsigned char * output = new unsigned char[outputSize]; int result = -1; if (stack->is<LUA_TSTRING>(5)){ const std::string ad = stack->toLString(5); result = mbedtls_cipher_auth_decrypt(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, reinterpret_cast<const unsigned char*>(tag.c_str()), tag.length() ); } else{ result = mbedtls_cipher_auth_decrypt(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, reinterpret_cast<const unsigned char*>(tag.c_str()), tag.length() ); } if (result == 0){ stack->pushLString(std::string(reinterpret_cast<char*>(output), outputSize)); delete[] output; } else{ stack->push<int>(result); } return 1; } return 0; }
static int aead_cipher_decrypt(cipher_ctx_t *cipher_ctx, uint8_t *p, size_t *plen, uint8_t *m, size_t mlen, uint8_t *ad, size_t adlen, uint8_t *n, uint8_t *k) { int err = CRYPTO_ERROR; unsigned long long long_plen = 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_decrypt_afternm(p, &long_plen, NULL, m, mlen, ad, adlen, n, (const aes256gcm_ctx *)cipher_ctx->aes256gcm_ctx); *plen = (size_t)long_plen; // 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_decrypt(cipher_ctx->evp, n, nlen, ad, adlen, m, mlen - tlen, p, plen, m + mlen - tlen, tlen); break; case CHACHA20POLY1305IETF: err = crypto_aead_chacha20poly1305_ietf_decrypt(p, &long_plen, NULL, m, mlen, ad, adlen, n, k); *plen = (size_t)long_plen; // it's safe to cast 64bit to 32bit length here break; #ifdef FS_HAVE_XCHACHA20IETF case XCHACHA20POLY1305IETF: err = crypto_aead_xchacha20poly1305_ietf_decrypt(p, &long_plen, NULL, m, mlen, ad, adlen, n, k); *plen = (size_t)long_plen; // it's safe to cast 64bit to 32bit length here break; #endif default: return CRYPTO_ERROR; } return err; }
static int aead_cipher_decrypt(cipher_ctx_t *cipher_ctx, uint8_t *p, size_t *plen, uint8_t *m, size_t mlen, uint8_t *ad, size_t adlen, uint8_t *n, uint8_t *k) { int err = CRYPTO_ERROR; unsigned long long long_plen = 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_decrypt(cipher_ctx->evp, n, nlen, ad, adlen, m, mlen - tlen, p, plen, m + mlen - tlen, tlen); break; case CHACHA20POLY1305IETF: err = crypto_aead_chacha20poly1305_ietf_decrypt(p, &long_plen, NULL, m, mlen, ad, adlen, n, k); *plen = (size_t)long_plen; // it's safe to cast 64bit to 32bit length here break; #ifdef FS_HAVE_XCHACHA20IETF case XCHACHA20POLY1305IETF: err = crypto_aead_xchacha20poly1305_ietf_decrypt(p, &long_plen, NULL, m, mlen, ad, adlen, n, k); *plen = (size_t)long_plen; // it's safe to cast 64bit to 32bit length here break; #endif default: return CRYPTO_ERROR; } return err; }