Skip to content

Commit 0dd9ee1

Browse files
committed
fix multi-threaded operation
Fixes #118, #130, #134
1 parent 66a4467 commit 0dd9ee1

29 files changed

+458
-63
lines changed

.cirrus.yml

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
task:
22
freebsd_instance:
3-
image_family: freebsd-14-0
3+
image_family: freebsd-14-2
44
env:
55
PKG_CONFIG_PATH: /usr/local/lib/pkgconfig
66
LD_LIBRARY_PATH: /usr/local/lib
@@ -34,14 +34,17 @@ task:
3434
ibmswtpm2-$IBMSWTPM_VER/src/tpm_server
3535

3636
run_abrmd_background_script: |
37-
sudo -u _tss tpm2-abrmd --tcti mssim:host=localhost,port=2321
37+
sleep 1
38+
/usr/sbin/daemon -P /var/run/tpm2_abrmd.pid -u _tss /usr/sbin/tpm2-abrmd --tcti "mssim:host=localhost,port=2321"
3839
3940
check_script: |
4041
openssl version
4142
tpm2_getcap properties-fixed | head -n 20
4243
gmake check
4344
4445
always:
46+
syslogs_script: |
47+
cp /var/log/messages test/system.log
4548
log_artifacts:
4649
path: test/**/*.log
4750
type: text/plain

.github/workflows/clang-asan-check.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
strategy:
1616
matrix:
1717
branch: [openssl-3.0, openssl-3.1, openssl-3.2, master]
18-
runs-on: ubuntu-latest
18+
runs-on: ubuntu-22.04
1919
steps:
2020
- uses: actions/checkout@v4
2121

.github/workflows/codeql.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88
jobs:
99
analyze:
1010
name: Analyze
11-
runs-on: ubuntu-latest
11+
runs-on: ubuntu-22.04
1212
permissions:
1313
actions: read
1414
contents: read
@@ -29,15 +29,15 @@ jobs:
2929
sudo apt-get install --yes autoconf-archive libtss2-dev
3030
3131
- name: Initialize CodeQL
32-
uses: github/codeql-action/init@v2
32+
uses: github/codeql-action/init@v3
3333
with:
3434
languages: ${{ matrix.language }}
3535
queries: +security-and-quality
3636

3737
- name: Autobuild
38-
uses: github/codeql-action/autobuild@v2
38+
uses: github/codeql-action/autobuild@v3
3939

4040
- name: Perform CodeQL Analysis
41-
uses: github/codeql-action/analyze@v2
41+
uses: github/codeql-action/analyze@v3
4242
with:
4343
category: "/language:${{ matrix.language }}"

.github/workflows/coverity-scan.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88
jobs:
99
latest:
1010
if: github.repository == 'tpm2-software/tpm2-openssl'
11-
runs-on: ubuntu-latest
11+
runs-on: ubuntu-22.04
1212
steps:
1313
- uses: actions/checkout@v4
1414

.github/workflows/gcc-distcheck.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ env:
88

99
jobs:
1010
build:
11-
runs-on: ubuntu-latest
11+
runs-on: ubuntu-22.04
1212
steps:
1313
- uses: actions/checkout@v4
1414

@@ -51,7 +51,7 @@ jobs:
5151
TPM2OPENSSL_TCTI: ${{ env.TCTI_ADDRESS }}
5252

5353
- name: Submit code coverage
54-
uses: codecov/codecov-action@v1.2.1
54+
uses: codecov/codecov-action@v5
5555

5656
- name: Check the distribution
5757
# AM_DISTCHECK_CONFIGURE_FLAGS are not ready for clang and asan

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ test/.dirstamp
2727
test/*.o
2828
test/*.trs
2929
test/selftest
30+
test/rand_processes
31+
test/rand_threads
3032
test/ec_genpkey_store_load
3133
test/ec_genpkey_x509_csr
3234
test/rsa_genpkey_decrypt

Makefile.am

+14
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ tpm2_la_SOURCES = \
77
src/tpm2-provider.c \
88
src/tpm2-provider.h \
99
src/tpm2-provider-core.c \
10+
src/tpm2-provider-semaphore.c \
11+
src/tpm2-provider-semaphore.h \
1012
src/tpm2-provider-types.c \
1113
src/tpm2-provider-types.h \
1214
src/tpm2-provider-x509.c \
@@ -58,6 +60,18 @@ test_selftest_CFLAGS = $(COMMON_CFLAGS)
5860
test_selftest_LDADD = $(CRYPTO_LIBS)
5961
test_selftest_LDFLAGS = $(COMMON_LDFLAGS)
6062

63+
check_PROGRAMS += test/rand_processes
64+
test_rand_processes_SOURCES = test/rand_processes.c
65+
test_rand_processes_CFLAGS = $(COMMON_CFLAGS)
66+
test_rand_processes_LDADD = $(CRYPTO_LIBS)
67+
test_rand_processes_LDFLAGS = $(COMMON_LDFLAGS)
68+
69+
check_PROGRAMS += test/rand_threads
70+
test_rand_threads_SOURCES = test/rand_threads.c
71+
test_rand_threads_CFLAGS = $(COMMON_CFLAGS)
72+
test_rand_threads_LDADD = $(CRYPTO_LIBS)
73+
test_rand_threads_LDFLAGS = $(COMMON_LDFLAGS)
74+
6175
check_PROGRAMS += test/ec_genpkey_store_load
6276
test_ec_genpkey_store_load_SOURCES = test/ec_genpkey_store_load.c
6377
test_ec_genpkey_store_load_CFLAGS = $(COMMON_CFLAGS)

docs/CHANGELOG.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
55

66
## [1.3.0] - 2024-xx-yy
77
### Added
8-
- Added support for RSA-OAEP decryption
9-
- Added Parent to textual information printed by 'openssl pkey -text'
8+
- Added support for RSA-OAEP decryption.
9+
- Added Parent to textual information printed by 'openssl pkey -text'.
1010
### Fixed
11+
- Fixed multi-threaded operation, preventing the 'Esys called in bad sequence'
12+
errors (thanks to @Danigaralfo, @famez, and @AndreasFuchsTPM).
1113
- Fixed handling of absent emptyAuth value in the TSS2 PRIVATE KEY file.
1214
- Set authorization value of newly generated keys. This allows users of the
1315
C API to direcly use just generated EVP_PKEY.

src/tpm2-provider-asymcipher-rsa.c

+6-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ typedef struct tpm2_rsa_asymcipher_ctx_st TPM2_RSA_ASYMCIPHER_CTX;
2020

2121
struct tpm2_rsa_asymcipher_ctx_st {
2222
const OSSL_CORE_HANDLE *core;
23+
tpm2_semaphore_t esys_lock;
2324
ESYS_CONTEXT *esys_ctx;
2425
TPM2_CAPABILITY capability;
2526
TPMT_RSA_DECRYPT decrypt;
@@ -47,6 +48,7 @@ static void
4748
return NULL;
4849

4950
actx->core = cprov->core;
51+
actx->esys_lock = cprov->esys_lock;
5052
actx->esys_ctx = cprov->esys_ctx;
5153
actx->capability = cprov->capability;
5254
actx->decrypt.scheme = TPM2_ALG_RSAES;
@@ -78,9 +80,12 @@ decrypt_message(TPM2_RSA_ASYMCIPHER_CTX *actx,
7880
cipher.size = inlen;
7981
memcpy(cipher.buffer, in, inlen);
8082

83+
if (!tpm2_semaphore_lock(actx->esys_lock))
84+
return 0;
8185
r = Esys_RSA_Decrypt(actx->esys_ctx, actx->pkey->object,
8286
ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
8387
&cipher, &actx->decrypt, &label, &actx->message);
88+
tpm2_semaphore_unlock(actx->esys_lock);
8489
TPM2_CHECK_RC(actx->core, r, TPM2_ERR_CANNOT_DECRYPT, return 0);
8590

8691
return 1;
@@ -114,9 +119,7 @@ rsa_asymcipher_freectx(void *ctx)
114119
if (actx == NULL)
115120
return;
116121

117-
if (actx->message != NULL)
118-
free(actx->message);
119-
122+
free(actx->message);
120123
OPENSSL_clear_free(actx, sizeof(TPM2_RSA_ASYMCIPHER_CTX));
121124
}
122125

src/tpm2-provider-cipher.c

+19-10
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ typedef struct tpm2_cipher_ctx_st TPM2_CIPHER_CTX;
1414

1515
struct tpm2_cipher_ctx_st {
1616
const OSSL_CORE_HANDLE *core;
17+
tpm2_semaphore_t esys_lock;
1718
ESYS_CONTEXT *esys_ctx;
1819
TPM2_CAPABILITY capability;
1920
ESYS_TR object;
@@ -46,6 +47,7 @@ tpm2_cipher_all_newctx(void *provctx,
4647
return NULL;
4748

4849
cctx->core = cprov->core;
50+
cctx->esys_lock = cprov->esys_lock;
4951
cctx->esys_ctx = cprov->esys_ctx;
5052
cctx->capability = cprov->capability;
5153
cctx->algorithm = algdef;
@@ -82,7 +84,7 @@ tpm2_cipher_freectx(void *ctx)
8284
if (cctx == NULL)
8385
return;
8486

85-
Esys_FlushContext(cctx->esys_ctx, cctx->object);
87+
tpm2_esys_flush_context(cctx->esys_lock, cctx->esys_ctx, cctx->object);
8688
OPENSSL_clear_free(cctx->ivector, sizeof(TPM2B_IV));
8789

8890
OPENSSL_clear_free(cctx, sizeof(TPM2_CIPHER_CTX));
@@ -127,18 +129,21 @@ tpm2_load_external_key(TPM2_CIPHER_CTX *cctx, ESYS_TR parent,
127129
TPM2B_PUBLIC *keyPublic = NULL;
128130
TPM2B_PRIVATE *keyPrivate = NULL;
129131

132+
if (!tpm2_semaphore_lock(cctx->esys_lock))
133+
return 0;
130134
/* older TPM2 chips do not support Esys_CreateLoaded */
131135
r = Esys_Create(cctx->esys_ctx, parent,
132136
ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
133137
&inSensitive, &inPublic, &outside_info, &creation_pcr,
134138
&keyPrivate, &keyPublic, NULL, NULL, NULL);
135-
TPM2_CHECK_RC(cctx->core, r, TPM2_ERR_CANNOT_CREATE_KEY, return 0);
136-
137-
r = Esys_Load(cctx->esys_ctx, parent,
138-
ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
139-
keyPrivate, keyPublic, &cctx->object);
140-
free(keyPublic);
141-
free(keyPrivate);
139+
if (!r) {
140+
r = Esys_Load(cctx->esys_ctx, parent,
141+
ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
142+
keyPrivate, keyPublic, &cctx->object);
143+
free(keyPublic);
144+
free(keyPrivate);
145+
}
146+
tpm2_semaphore_unlock(cctx->esys_lock);
142147
TPM2_CHECK_RC(cctx->core, r, TPM2_ERR_CANNOT_CREATE_KEY, return 0);
143148

144149
return 1;
@@ -158,12 +163,13 @@ tpm2_cipher_init(TPM2_CIPHER_CTX *cctx,
158163
DBG("CIPHER %sCRYPT_INIT load key %zu bytes\n",
159164
cctx->decrypt ? "DE" : "EN", keylen);
160165

161-
if (!tpm2_build_primary(cctx->core, cctx->esys_ctx, cctx->capability.algorithms,
166+
if (!tpm2_build_primary(cctx->core, cctx->esys_lock, cctx->esys_ctx,
167+
cctx->capability.algorithms,
162168
ESYS_TR_RH_NULL, NULL, &parent))
163169
return 0;
164170

165171
res = tpm2_load_external_key(cctx, parent, key, keylen);
166-
Esys_FlushContext(cctx->esys_ctx, parent);
172+
tpm2_esys_flush_context(cctx->esys_lock, cctx->esys_ctx, parent);
167173
if (!res)
168174
return 0;
169175
}
@@ -212,6 +218,8 @@ encrypt_decrypt(TPM2_CIPHER_CTX *cctx,
212218
{
213219
TSS2_RC r;
214220

221+
if (!tpm2_semaphore_lock(cctx->esys_lock))
222+
return 0;
215223
r = Esys_EncryptDecrypt2(cctx->esys_ctx, cctx->object,
216224
ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
217225
&cctx->buffer, cctx->decrypt, TPM2_ALG_NULL,
@@ -222,6 +230,7 @@ encrypt_decrypt(TPM2_CIPHER_CTX *cctx,
222230
cctx->decrypt, TPM2_ALG_NULL, cctx->ivector,
223231
&cctx->buffer, outbuff, ivector);
224232
}
233+
tpm2_semaphore_unlock(cctx->esys_lock);
225234

226235
return r;
227236
}

src/tpm2-provider-core.c

+28
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,34 @@ tpm2_list_params(const char *text, const OSSL_PARAM params[])
100100
fprintf(stderr, " ]\n");
101101
}
102102

103+
TSS2_RC
104+
tpm2_esys_tr_close(tpm2_semaphore_t esys_lock, ESYS_CONTEXT *esys_ctx, ESYS_TR *object)
105+
{
106+
TSS2_RC r;
107+
108+
if (!tpm2_semaphore_lock(esys_lock))
109+
return TSS2_ESYS_RC_GENERAL_FAILURE;
110+
111+
r = Esys_TR_Close(esys_ctx, object);
112+
113+
tpm2_semaphore_unlock(esys_lock);
114+
return r;
115+
}
116+
117+
TSS2_RC
118+
tpm2_esys_flush_context(tpm2_semaphore_t esys_lock, ESYS_CONTEXT *esys_ctx, ESYS_TR flush_handle)
119+
{
120+
TSS2_RC r;
121+
122+
if (!tpm2_semaphore_lock(esys_lock))
123+
return TSS2_ESYS_RC_GENERAL_FAILURE;
124+
125+
r = Esys_FlushContext(esys_ctx, flush_handle);
126+
127+
tpm2_semaphore_unlock(esys_lock);
128+
return r;
129+
}
130+
103131
int
104132
tpm2_supports_algorithm(const TPMS_CAPABILITY_DATA *caps, TPM2_ALG_ID algorithm)
105133
{

0 commit comments

Comments
 (0)