Skip to content

Commit bed73b6

Browse files
committed
Merge remote-tracking branch 'origin/refs/pull/201/head'
2 parents b9212f4 + 2922f43 commit bed73b6

File tree

4 files changed

+96
-0
lines changed

4 files changed

+96
-0
lines changed

doc/luaossl.pdf

147 KB
Binary file not shown.

doc/luaossl.tex

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,6 +1485,14 @@ \section{Modules}
14851485

14861486
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.
14871487

1488+
\subsubsection[\fn{cipher:getTag}]{\fn{cipher:getTag($len$)}}
1489+
1490+
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()}).
1491+
1492+
\subsubsection[\fn{cipher:setTag}]{\fn{cipher:setTag($tag$)}}
1493+
1494+
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.
1495+
14881496
\end{Module}
14891497

14901498

regress/115-test-aead.lua

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
local regress = require "regress";
2+
local openssl = require "openssl";
3+
local cipher = require "openssl.cipher"
4+
5+
6+
-- Test AES-256-GCM
7+
local key = "abcdefghijklmnopabcdefghijklmnop"
8+
local iv = "123456123456"
9+
local message = "My secret message"
10+
11+
function test_aead(params)
12+
local c = cipher.new(params.cipher):encrypt(key, iv)
13+
14+
local encrypted = c:update(message)
15+
regress.check(encrypted)
16+
regress.check(c:final(), "fail final encrypt")
17+
18+
local tag = assert(c:getTag(params.tag_length))
19+
regress.check(tag and #tag == params.tag_length)
20+
21+
22+
-- Now for the decryption
23+
local d = cipher.new(params.cipher):decrypt(key, iv)
24+
d:setTag(tag);
25+
26+
local decrypted = d:update(encrypted)
27+
regress.check(decrypted == message, "decrypted message doesn't match")
28+
regress.check(d:final(), "fail final decrypt")
29+
end
30+
31+
test_aead {
32+
cipher = "aes-256-gcm";
33+
tag_length = 16;
34+
}
35+
36+
test_aead {
37+
cipher = "aes-256-ccm";
38+
tag_length = 12;
39+
}

src/openssl.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12020,6 +12020,53 @@ static int cipher_final(lua_State *L) {
1202012020
} /* cipher_final() */
1202112021

1202212022

12023+
static int cipher_get_tag(lua_State *L) {
12024+
EVP_CIPHER_CTX *ctx = checksimple(L, 1, CIPHER_CLASS);
12025+
luaL_Buffer tag;
12026+
size_t tag_size = luaL_checkinteger(L, 2);
12027+
12028+
luaL_buffinit(L, &tag);
12029+
12030+
/* EVP_CTRL_GCM_GET_TAG is works for both GCM and CCM and across all
12031+
* supported OpenSSL versions. We can switch to the unified identifier
12032+
* 'EVP_CTRL_AEAD_GET_TAG' in OpenSSL 1.1+.
12033+
*/
12034+
if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, tag_size, (void*)luaL_prepbuffsize(&tag, tag_size))) {
12035+
goto sslerr;
12036+
}
12037+
12038+
luaL_pushresultsize(&tag, tag_size);
12039+
12040+
return 1;
12041+
12042+
sslerr:
12043+
lua_pushnil(L);
12044+
auxL_pusherror(L, auxL_EOPENSSL, NULL);
12045+
12046+
return 2;
12047+
} /* cipher_get_tag() */
12048+
12049+
12050+
static int cipher_set_tag(lua_State *L) {
12051+
EVP_CIPHER_CTX *ctx = checksimple(L, 1, CIPHER_CLASS);
12052+
size_t tag_size;
12053+
const char* tag = luaL_checklstring(L, 2, &tag_size);
12054+
if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, tag_size, (void*)tag)) {
12055+
goto sslerr;
12056+
}
12057+
12058+
lua_pushlstring(L, tag, tag_size);
12059+
12060+
return 1;
12061+
12062+
sslerr:
12063+
lua_pushnil(L);
12064+
auxL_pusherror(L, auxL_EOPENSSL, NULL);
12065+
12066+
return 2;
12067+
} /* cipher_set_tag() */
12068+
12069+
1202312070
static int cipher__gc(lua_State *L) {
1202412071
EVP_CIPHER_CTX **ctx = luaL_checkudata(L, 1, CIPHER_CLASS);
1202512072

@@ -12035,6 +12082,8 @@ static const auxL_Reg cipher_methods[] = {
1203512082
{ "decrypt", &cipher_decrypt },
1203612083
{ "update", &cipher_update },
1203712084
{ "final", &cipher_final },
12085+
{ "getTag", &cipher_get_tag },
12086+
{ "setTag", &cipher_set_tag },
1203812087
{ NULL, NULL },
1203912088
};
1204012089

0 commit comments

Comments
 (0)