aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 },
};