diff options
author | daurnimator <quae@daurnimator.com> | 2022-07-03 22:54:31 +1000 |
---|---|---|
committer | daurnimator <quae@daurnimator.com> | 2022-07-03 22:56:07 +1000 |
commit | bed73b66dee1dde0bfa5a658cf109457c3f70b46 (patch) | |
tree | 932f7b82052832b459f607323a92dad8929014dc | |
parent | b9212f4029be6d51d12ac0414b06eb9fe450a0e3 (diff) | |
parent | 2922f436c562cf4dc716fc24816784b71da27403 (diff) | |
download | luaossl-bed73b66dee1dde0bfa5a658cf109457c3f70b46.tar.gz luaossl-bed73b66dee1dde0bfa5a658cf109457c3f70b46.tar.bz2 luaossl-bed73b66dee1dde0bfa5a658cf109457c3f70b46.zip |
Merge remote-tracking branch 'origin/refs/pull/201/head'
-rw-r--r-- | doc/luaossl.pdf | bin | 182982 -> 333327 bytes | |||
-rw-r--r-- | doc/luaossl.tex | 8 | ||||
-rw-r--r-- | regress/115-test-aead.lua | 39 | ||||
-rw-r--r-- | src/openssl.c | 49 |
4 files changed, 96 insertions, 0 deletions
diff --git a/doc/luaossl.pdf b/doc/luaossl.pdf Binary files differindex b7a09dc..b8a0e27 100644 --- a/doc/luaossl.pdf +++ b/doc/luaossl.pdf diff --git a/doc/luaossl.tex b/doc/luaossl.tex index efc6422..df5626a 100644 --- a/doc/luaossl.tex +++ b/doc/luaossl.tex @@ -1485,6 +1485,14 @@ Update the cipher instance with the specified string(s). Returns a string on suc Update the cipher with the specified string(s). Returns the final output string on success, or nil and an error message on failure. The returned string may be empty if all blocks have already been flushed in prior \fn{:update} calls. +\subsubsection[\fn{cipher:getTag}]{\fn{cipher:getTag($len$)}} + +Returns the authentication tag for the ciphertext (GCM ciphers only) as a binary string. This method can only be called when encrypting data, and must be called after all data has been processed (i.e. after calling \fn{:final()}). + +\subsubsection[\fn{cipher:setTag}]{\fn{cipher:setTag($tag$)}} + +Sets the provided binary string as the expected authentication tag for the forthcoming ciphertext (GCM ciphers only). This method can only be called when decrypting data, and must be called before \fn{:final()} to ensure the ciphertext integrity can be verified successfully. + \end{Module} diff --git a/regress/115-test-aead.lua b/regress/115-test-aead.lua new file mode 100644 index 0000000..ed0f7f8 --- /dev/null +++ b/regress/115-test-aead.lua @@ -0,0 +1,39 @@ +local regress = require "regress"; +local openssl = require "openssl"; +local cipher = require "openssl.cipher" + + +-- Test AES-256-GCM +local key = "abcdefghijklmnopabcdefghijklmnop" +local iv = "123456123456" +local message = "My secret message" + +function test_aead(params) + local c = cipher.new(params.cipher):encrypt(key, iv) + + local encrypted = c:update(message) + regress.check(encrypted) + regress.check(c:final(), "fail final encrypt") + + local tag = assert(c:getTag(params.tag_length)) + regress.check(tag and #tag == params.tag_length) + + + -- Now for the decryption + local d = cipher.new(params.cipher):decrypt(key, iv) + d:setTag(tag); + + local decrypted = d:update(encrypted) + regress.check(decrypted == message, "decrypted message doesn't match") + regress.check(d:final(), "fail final decrypt") +end + +test_aead { + cipher = "aes-256-gcm"; + tag_length = 16; +} + +test_aead { + cipher = "aes-256-ccm"; + tag_length = 12; +} diff --git a/src/openssl.c b/src/openssl.c index 198e6a6..3506089 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -12020,6 +12020,53 @@ sslerr: } /* cipher_final() */ +static int cipher_get_tag(lua_State *L) { + EVP_CIPHER_CTX *ctx = checksimple(L, 1, CIPHER_CLASS); + luaL_Buffer tag; + size_t tag_size = luaL_checkinteger(L, 2); + + luaL_buffinit(L, &tag); + + /* EVP_CTRL_GCM_GET_TAG is works for both GCM and CCM and across all + * supported OpenSSL versions. We can switch to the unified identifier + * 'EVP_CTRL_AEAD_GET_TAG' in OpenSSL 1.1+. + */ + if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, tag_size, (void*)luaL_prepbuffsize(&tag, tag_size))) { + goto sslerr; + } + + luaL_pushresultsize(&tag, tag_size); + + return 1; + +sslerr: + lua_pushnil(L); + auxL_pusherror(L, auxL_EOPENSSL, NULL); + + return 2; +} /* cipher_get_tag() */ + + +static int cipher_set_tag(lua_State *L) { + EVP_CIPHER_CTX *ctx = checksimple(L, 1, CIPHER_CLASS); + size_t tag_size; + const char* tag = luaL_checklstring(L, 2, &tag_size); + if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, tag_size, (void*)tag)) { + goto sslerr; + } + + lua_pushlstring(L, tag, tag_size); + + return 1; + +sslerr: + lua_pushnil(L); + auxL_pusherror(L, auxL_EOPENSSL, NULL); + + return 2; +} /* cipher_set_tag() */ + + static int cipher__gc(lua_State *L) { EVP_CIPHER_CTX **ctx = luaL_checkudata(L, 1, CIPHER_CLASS); @@ -12035,6 +12082,8 @@ static const auxL_Reg cipher_methods[] = { { "decrypt", &cipher_decrypt }, { "update", &cipher_update }, { "final", &cipher_final }, + { "getTag", &cipher_get_tag }, + { "setTag", &cipher_set_tag }, { NULL, NULL }, }; |