Skip to content

Commit 014f5b3

Browse files
authored
Merge pull request #59 from gasbytes/samba-libs
samba-libs and dynamic AAD allocation (AES-GCM)
2 parents 13c29c1 + 41123b4 commit 014f5b3

4 files changed

Lines changed: 299 additions & 20 deletions

File tree

.github/workflows/deb.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ jobs:
4343
'CFLAGS=-DWOLFSSL_PUBLIC_ASN -DHAVE_FFDHE_3072 -DHAVE_FFDHE_4096 -DWOLFSSL_DH_EXTRA -DWOLFSSL_PSS_SALT_LEN_DISCOVER -DWOLFSSL_PUBLIC_MP -DWOLFSSL_RSA_KEY_CHECK -DHAVE_FFDHE_Q -DHAVE_FFDHE_6144 -DHAVE_FFDHE_8192 -DWOLFSSL_ECDSA_DETERMINISTIC_K -DWOLFSSL_VALIDATE_ECC_IMPORT -DRSA_MIN_SIZE=1024'
4444
make -j"$(nproc)"
4545
sudo make deb
46-
sudo dpkg -i libwolfssl_*.deb libwolfssl-dev_*.deb
46+
sudo dpkg -i ../libwolfssl_*.deb ../libwolfssl-dev_*.deb ../libwolfssl-dbgsym_*.deb
4747
4848
- name: Build .deb set (gnutls-wolfssl non-FIPS)
4949
run: dpkg-buildpackage -us -uc -b

.github/workflows/samba-libs.yml

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
name: Samba-libs Test
2+
3+
on:
4+
push:
5+
branches: [ 'master', 'main', 'release/**' ]
6+
pull_request:
7+
branches: [ '*' ]
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
build_samba_libs:
15+
timeout-minutes: 60
16+
strategy:
17+
matrix:
18+
os: [ ubuntu-latest ]
19+
samba_ref: [ 'master' ]
20+
fail-fast: false
21+
runs-on: ${{ matrix.os }}
22+
container:
23+
image: debian:bookworm
24+
25+
steps:
26+
- uses: actions/checkout@v4
27+
28+
- name: Set up build tool-chain
29+
run: |
30+
apt-get update
31+
apt-get install -y sudo wget build-essential pkg-config \
32+
git \
33+
libacl1-dev libldap2-dev libpam0g-dev \
34+
attr krb5-user dnsutils \
35+
gnulib autopoint gperf gtk-doc-tools nettle-dev clang \
36+
libtasn1-bin libtasn1-6-dev libunistring-dev libp11-kit-dev libunbound-dev \
37+
liblmdb-dev libparse-yapp-perl libgpgme11-dev libjansson-dev libarchive-dev \
38+
libdbus-1-dev python3-dnspython python3-markdown libpopt-dev heimdal-dev \
39+
libtirpc-dev
40+
apt-get install -y \
41+
libkrb5-dev libsasl2-dev libssl-dev libcap-dev \
42+
libcups2-dev libavahi-client-dev libavahi-common-dev liburing-dev \
43+
gdb libgpgme-dev
44+
apt-get install -y acl attr autoconf bind9utils bison build-essential \
45+
debhelper dnsutils docbook-xml docbook-xsl flex gdb libjansson-dev krb5-user \
46+
libacl1-dev libaio-dev libarchive-dev libattr1-dev libblkid-dev libbsd-dev \
47+
libcap-dev libcups2-dev libgpgme-dev libjson-perl \
48+
libldap2-dev libncurses5-dev libpam0g-dev libparse-yapp-perl \
49+
libpopt-dev libreadline-dev nettle-dev perl pkg-config \
50+
python3-dev python3-dbg python3-cryptography python3-dnspython python3-gpg python3-markdown \
51+
xsltproc zlib1g-dev liblmdb-dev lmdb-utils python3-pyasn1 python3-iso8601
52+
53+
- name: Restore cached gnutls-wolfssl
54+
id: cache-gnutls
55+
uses: actions/cache@v4
56+
with:
57+
path: |
58+
/opt/gnutls
59+
/opt/wolfssl
60+
/opt/wolfssl-gnutls-wrapper
61+
key: gnutls-wolfssl-${{ runner.os }}-${{ hashFiles('setup.sh', 'wolfssl-gnutls-wrapper/**', 'wolfssl/**', 'gnutls/**') }}
62+
restore-keys: |
63+
gnutls-wolfssl-${{ runner.os }}-
64+
65+
- name: Build GnuTLS with wolfSSL provider using setup.sh script
66+
if: steps.cache-gnutls.outputs.cache-hit != 'true'
67+
run: |
68+
echo "Running setup.sh..."
69+
GNUTLS_INSTALL=/opt/gnutls WOLFSSL_INSTALL=/opt/wolfssl ./setup.sh
70+
71+
- name: Verify provider artefacts exist
72+
run: |
73+
test -d /opt/wolfssl || exit 1
74+
test -d /opt/gnutls || exit 1
75+
test -d /opt/wolfssl-gnutls-wrapper/lib || exit 1
76+
77+
- name: Clone Samba
78+
run: |
79+
git clone https://gitlab.com/samba-team/samba.git samba
80+
cd samba
81+
if [ "${{ matrix.samba_ref }}" != "master" ]; then
82+
git checkout ${{ matrix.samba_ref }}
83+
fi
84+
85+
- name: Configure & build Samba-libs
86+
working-directory: samba
87+
run: |
88+
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH:+$PKG_CONFIG_PATH:}/opt/gnutls/lib/pkgconfig"
89+
export CPPFLAGS="-I/opt/gnutls/include ${CPPFLAGS:-}"
90+
export LDFLAGS="-L/opt/gnutls/lib -L/usr/lib/x86_64-linux-gnu -Wl,-rpath,/opt/gnutls/lib ${LDFLAGS:-}"
91+
export LD_LIBRARY_PATH="/opt/gnutls/lib:/usr/lib/x86_64-linux-gnu:${LD_LIBRARY_PATH:-}"
92+
./configure --enable-selftest
93+
make -j"$(nproc)"
94+
95+
- name: Run quick-tests
96+
working-directory: samba
97+
run: |
98+
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH:+$PKG_CONFIG_PATH:}/opt/gnutls/lib/pkgconfig"
99+
export CPPFLAGS="-I/opt/gnutls/include ${CPPFLAGS:-}"
100+
export LDFLAGS="-L/opt/gnutls/lib -L/usr/lib/x86_64-linux-gnu -Wl,-rpath,/opt/gnutls/lib ${LDFLAGS:-}"
101+
export LD_LIBRARY_PATH="/opt/gnutls/lib:/usr/lib/x86_64-linux-gnu:${LD_LIBRARY_PATH:-}"
102+
make quicktest -j"$(nproc)"

wolfssl-gnutls-wrapper/src/cipher.c

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ enum {
3131
/** Maximum AES key size. */
3232
#define MAX_AES_KEY_SIZE AES_256_KEY_SIZE
3333
/** Maximum authentication data. */
34-
#define MAX_AUTH_DATA 1024
34+
#define MAX_AUTH_DATA 4096
3535
/** Maximum plaintext to encrypt for GCM */
3636
#define MAX_AES_GCM_PLAINTEXT ((1ULL << 36) - 32)
3737
/** Maximum RSA-PSS signature size */
@@ -82,10 +82,14 @@ struct wolfssl_cipher_ctx {
8282
size_t iv_size;
8383

8484
/* For GCM mode. */
85-
/** Authentication data to use. */
86-
unsigned char auth_data[MAX_AUTH_DATA];
87-
/** Size of authentication data to use. */
85+
/** Authentication data to use (static, maximum 4096 bytes). */
86+
unsigned char auth_data_static[MAX_AUTH_DATA];
87+
/** Authentication data to use (allocated dynamically). */
88+
unsigned char *auth_data_heap;
89+
/** Size of authentication data to use (static). */
8890
size_t auth_data_size;
91+
/** Size of authentication data to use (heap). */
92+
size_t auth_alloc;
8993
/** Calculated authentication tag. */
9094
unsigned char tag[GCM_TAG_SIZE];
9195
/** Size of calculated authentication tag. */
@@ -240,6 +244,7 @@ int wolfssl_cipher_init(gnutls_cipher_algorithm_t algorithm, void **_ctx,
240244
ctx->tag_set_ext = 0;
241245
ctx->algorithm = 0;
242246
ctx->data_size = 0;
247+
ctx->auth_data_heap = NULL;
243248

244249
ctx->algorithm = algorithm;
245250
ctx->mode = get_cipher_mode(algorithm);
@@ -671,12 +676,47 @@ int wolfssl_cipher_auth(void *_ctx, const void *auth_data,
671676
return GNUTLS_E_INVALID_REQUEST;
672677
}
673678

674-
/* Check authentication data will fit in cache. */
675-
if (ctx->auth_data_size + auth_size > sizeof(ctx->auth_data)) {
676-
WGW_ERROR("Auth data too big: %ld + %ld > %ld", ctx->auth_data_size,
677-
auth_size, sizeof(ctx->auth_data));
678-
return GNUTLS_E_SHORT_MEMORY_BUFFER;
679-
}
679+
/* Check authentication data will fit in the static cache,
680+
* switch to heap if it doesn't. */
681+
if (ctx->auth_data_heap == NULL &&
682+
ctx->auth_data_size + auth_size > sizeof(ctx->auth_data_static)) {
683+
WGW_LOG("Auth data too big: %ld + %ld > %ld", ctx->auth_data_size,
684+
auth_size, sizeof(ctx->auth_data_static));
685+
WGW_LOG("Switching to dynamic allocation");
686+
687+
size_t new_sz = sizeof(ctx->auth_data_static);
688+
while (new_sz < ctx->auth_data_size + auth_size)
689+
new_sz *= 2;
690+
691+
ctx->auth_data_heap = gnutls_malloc(new_sz);
692+
if (!ctx->auth_data_heap) {
693+
WGW_ERROR("gnutls_malloc failed for auth_data_heap");
694+
return GNUTLS_E_MEMORY_ERROR;
695+
}
696+
ctx->auth_alloc = new_sz;
697+
XMEMCPY(ctx->auth_data_heap, ctx->auth_data_static,
698+
ctx->auth_data_size);
699+
WGW_LOG("Spilled AAD to heap (%zu bytes)", new_sz);
700+
}
701+
702+
/* We are already storing in the heap, we check
703+
* if we need to grow it. */
704+
if (ctx->auth_data_heap &&
705+
ctx->auth_data_size + auth_size > ctx->auth_alloc) {
706+
WGW_LOG("New auth data too big, reallocating");
707+
size_t new_sz = ctx->auth_alloc;
708+
while (new_sz < ctx->auth_data_size + auth_size)
709+
new_sz *= 2;
710+
711+
unsigned char *p = gnutls_realloc(ctx->auth_data_heap, new_sz);
712+
if (!p) {
713+
WGW_ERROR("gnutls_realloc failed for auth_data_heap");
714+
return GNUTLS_E_MEMORY_ERROR;
715+
}
716+
ctx->auth_data_heap = p;
717+
ctx->auth_alloc = new_sz;
718+
WGW_LOG("Grew AAD heap to %zu bytes", new_sz);
719+
}
680720

681721
/* Streaming must be a multiple of block size except for last. */
682722
if ((ctx->auth_data_size % AES_BLOCK_SIZE) != 0) {
@@ -685,8 +725,11 @@ int wolfssl_cipher_auth(void *_ctx, const void *auth_data,
685725
}
686726

687727
/* Store AAD for later use in encrypt/decrypt operations. */
688-
XMEMCPY(ctx->auth_data + ctx->auth_data_size, auth_data, auth_size);
689-
ctx->auth_data_size += auth_size;
728+
unsigned char *dst = ctx->auth_data_heap ?
729+
ctx->auth_data_heap : ctx->auth_data_static;
730+
731+
XMEMCPY(dst + ctx->auth_data_size, auth_data, auth_size);
732+
ctx->auth_data_size += auth_size;
690733

691734
WGW_LOG("AAD added successfully");
692735
return 0;
@@ -751,7 +794,7 @@ int wolfssl_cipher_encrypt(void *_ctx, const void *src, size_t src_size,
751794
unsigned char* ptr;
752795
unsigned char* encr;
753796

754-
WGW_LOG("Caching platintext");
797+
WGW_LOG("Caching plaintext");
755798

756799
ctx->enc = 1;
757800

@@ -782,11 +825,13 @@ int wolfssl_cipher_encrypt(void *_ctx, const void *src, size_t src_size,
782825
WGW_ERROR("realloc of gmac data failed");
783826
return GNUTLS_E_INVALID_REQUEST;
784827
}
828+
unsigned char *aad = ctx->auth_data_heap ?
829+
ctx->auth_data_heap : ctx->auth_data_static;
785830

786831
/* Do encryption with the data we have. */
787832
ret = wc_AesGcmEncrypt(&ctx->cipher.aes_ctx, encr,
788833
ctx->data, ctx->data_size, ctx->iv, ctx->iv_size,
789-
ctx->tag, ctx->tag_size, ctx->auth_data, ctx->auth_data_size);
834+
ctx->tag, ctx->tag_size, aad, ctx->auth_data_size);
790835
if (ret != 0) {
791836
WGW_WOLFSSL_ERROR("wc_AesGcmEncrypt", ret);
792837
gnutls_free(encr);
@@ -894,7 +939,7 @@ int wolfssl_cipher_decrypt(void *_ctx, const void *src, size_t src_size,
894939
unsigned char* ptr;
895940
unsigned char* decr;
896941

897-
WGW_LOG("Caching platintext");
942+
WGW_LOG("Caching plaintext");
898943

899944
ctx->enc = 1;
900945

@@ -922,14 +967,18 @@ int wolfssl_cipher_decrypt(void *_ctx, const void *src, size_t src_size,
922967
}
923968

924969
WGW_LOG("wc_AesGcmDecrypt");
970+
971+
unsigned char *aad = ctx->auth_data_heap ?
972+
ctx->auth_data_heap : ctx->auth_data_static;
973+
925974
/* If caller hasn't set tag then we are creating it. */
926975
if (!ctx->tag_set_ext) {
927976
/* Encrypt the ciphertext to get the plaintext.
928977
* Tag will have been created on plaintext which is of no use.
929978
*/
930979
ret = wc_AesGcmEncrypt(&ctx->cipher.aes_ctx, decr, ctx->data,
931980
ctx->data_size, ctx->iv, ctx->iv_size,
932-
ctx->tag, ctx->tag_size, ctx->auth_data, ctx->auth_data_size);
981+
ctx->tag, ctx->tag_size, aad, ctx->auth_data_size);
933982
if (ret != 0) {
934983
WGW_WOLFSSL_ERROR("wc_AesGcmEncrypt", ret);
935984
gnutls_free(decr);
@@ -938,7 +987,7 @@ int wolfssl_cipher_decrypt(void *_ctx, const void *src, size_t src_size,
938987
/* Encrypt the plaintext to create the tag. */
939988
ret = wc_AesGcmEncrypt(&ctx->cipher.aes_ctx, decr, decr,
940989
ctx->data_size, ctx->iv, ctx->iv_size,
941-
ctx->tag, ctx->tag_size, ctx->auth_data, ctx->auth_data_size);
990+
ctx->tag, ctx->tag_size, aad, ctx->auth_data_size);
942991
if (ret != 0) {
943992
WGW_WOLFSSL_ERROR("wc_AesGcmEncrypt", ret);
944993
gnutls_free(decr);
@@ -950,7 +999,7 @@ int wolfssl_cipher_decrypt(void *_ctx, const void *src, size_t src_size,
950999
/* Do decryption with cipehtext, IV, authentication data and tag. */
9511000
ret = wc_AesGcmDecrypt(&ctx->cipher.aes_ctx, decr,
9521001
ctx->data, ctx->data_size, ctx->iv, ctx->iv_size,
953-
ctx->tag, ctx->tag_size, ctx->auth_data, ctx->auth_data_size);
1002+
ctx->tag, ctx->tag_size, aad, ctx->auth_data_size);
9541003
if (ret != 0) {
9551004
WGW_WOLFSSL_ERROR("wc_AesGcmEncrypt", ret);
9561005
gnutls_free(decr);
@@ -1044,9 +1093,12 @@ void wolfssl_cipher_tag(void *_ctx, void *tag, size_t tag_size)
10441093
if (ctx->mode == GCM) {
10451094
WGW_LOG("wc_AesGcmEncrypt");
10461095

1096+
unsigned char *aad = ctx->auth_data_heap ?
1097+
ctx->auth_data_heap : ctx->auth_data_static;
1098+
10471099
/* Do authentication with no plaintext. */
10481100
ret = wc_AesGcmEncrypt(&ctx->cipher.aes_ctx, NULL, NULL, 0, ctx->iv,
1049-
ctx->iv_size, ctx->tag, ctx->tag_size, ctx->auth_data,
1101+
ctx->iv_size, ctx->tag, ctx->tag_size, aad,
10501102
ctx->auth_data_size);
10511103
if (ret != 0) {
10521104
WGW_WOLFSSL_ERROR("wc_AesGcmEncrypt", ret);
@@ -1264,6 +1316,9 @@ void wolfssl_cipher_deinit(void *_ctx)
12641316
ctx->initialized = 0;
12651317
ctx->enc_initialized = 0;
12661318
ctx->dec_initialized = 0;
1319+
if (ctx->auth_data_heap) {
1320+
gnutls_free(ctx->auth_data_heap);
1321+
}
12671322
}
12681323

12691324
gnutls_free(ctx);

0 commit comments

Comments
 (0)