aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatarLibravatar Matthew Wild <mwild1@gmail.com> 2022-06-29 13:22:18 +0100
committerLibravatarLibravatar daurnimator <quae@daurnimator.com> 2022-07-03 22:55:59 +1000
commitdb44f3e7b6779e8238a5d801c8f35041ad9baabb (patch)
tree18a41fc1c74d48d5e2dc46fcc2f9d20945145efe
parented61d8d863163b216d5996c850c0a1fa2171e0a4 (diff)
downloadluaossl-db44f3e7b6779e8238a5d801c8f35041ad9baabb.tar.gz
luaossl-db44f3e7b6779e8238a5d801c8f35041ad9baabb.tar.bz2
luaossl-db44f3e7b6779e8238a5d801c8f35041ad9baabb.zip
Add support for getting/setting GCM authentication tag (fixes #115)
-rw-r--r--doc/luaossl.pdfbin182982 -> 333327 bytes
-rw-r--r--doc/luaossl.tex8
-rw-r--r--src/openssl.c49
3 files changed, 57 insertions, 0 deletions
diff --git a/doc/luaossl.pdf b/doc/luaossl.pdf
index b7a09dc..b8a0e27 100644
--- a/doc/luaossl.pdf
+++ b/doc/luaossl.pdf
Binary files differ
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/src/openssl.c b/src/openssl.c
index b56c78a..b30635b 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -11975,6 +11975,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);
@@ -11990,6 +12037,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 },
};