Repository navigation
459 lines (418 loc) · 21 KB
/
Copy pathautosar.yml
File metadata and controls
459 lines (418 loc) · 21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
name: AUTOSAR Tests
# START OF COMMON SECTION
on:
push:
branches: [ 'release/**' ]
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
branches: [ '*' ]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
# END OF COMMON SECTION
jobs:
autosar_port_test:
name: AUTOSAR port test (${{ matrix.name }})
if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }}
runs-on: ubuntu-24.04
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
include:
# Default key selection: GetKey() scans the keystore and takes the
# first slot whose key element ID and key length match the job.
# Covers singleshot_test, update_test, random_test and key_test.
- name: default
config: "--enable-autosar"
expect_redirect: false
# Key input redirection pins each key element to one keystore slot at
# compile time. Nothing built this half of the port before: GetKey()
# used runtime struct members as switch case labels, so no build with
# REDIRECTION_CONFIG defined compiled at all, and redirect_test is
# gated behind that same macro -- the one test covering the feature
# could never run. The slot assignment below is the port README's
# example config: cipher key to slot 1, cipher IV to slot 4.
- name: key-redirection
config: >-
--enable-autosar
CPPFLAGS="-DREDIRECTION_CONFIG=0x03
-DREDIRECTION_IN1_KEYID=1 -DREDIRECTION_IN1_KEYELMID=0x01
-DREDIRECTION_IN2_KEYID=4 -DREDIRECTION_IN2_KEYELMID=0x05"
expect_redirect: true
# The MAC services are an add-on enable, so they need their own entry:
# nothing else builds csm.c's Csm_MacGenerate/Csm_MacVerify or the
# driver's CMAC path, and mac_test is compiled in only here. The entry
# also covers the option pulling wolfCrypt's CMAC in by itself --
# WOLFSSL_AES_DIRECT included, without which wc_InitCmac() compiles
# fine and then fails at runtime.
- name: cmac
config: "--enable-autosar --enable-autosar-cmac"
expect_redirect: false
expect_mac: true
# Csm_ConfigType's devId is what turns the Crypto driver into a front
# end for an HSM, and devid_test is compiled in only with the crypto
# callback machinery present. It registers a counting callback and
# asserts the cipher, MAC and RNG jobs all reach it with the right
# devId, and that Csm_Init(NULL) still runs entirely in software.
- name: cryptocb
config: >-
--enable-autosar --enable-autosar-cmac --enable-cryptocb
CPPFLAGS=-DWOLF_CRYPTO_CB_FREE
expect_redirect: false
expect_mac: true
expect_devid: true
# Key handles: a keystore slot names a key in the device instead of
# holding it, so the key never enters RAM. keyhandle_test checks that
# a named key produces the same ciphertext as the key itself, which
# is what proves the identifier reached the device rather than
# something merely looking encrypted. WOLF_PRIVATE_KEY_ID is a raw
# -D, not a configure option.
- name: keyhandle
config: >-
--enable-autosar --enable-autosar-cmac --enable-cryptocb
CPPFLAGS="-DWOLF_PRIVATE_KEY_ID -DWOLF_CRYPTO_CB_FREE"
expect_redirect: false
expect_mac: true
expect_devid: true
expect_keyhandle: true
# Development error reporting. With WOLFSSL_AUTOSAR_DET the port
# forwards to Det_ReportError(), which the test program supplies --
# hence the static build, so the undefined symbol resolves from the
# application rather than from the shared library. det_test asserts
# the module and error IDs are the ones the CSM specification
# assigns; an earlier version of this port reported a local 0-based
# enum, so every ID a DET would have seen was wrong.
- name: det
config: >-
--enable-autosar --enable-autosar-cmac
--enable-static --disable-shared
CPPFLAGS=-DWOLFSSL_AUTOSAR_DET
expect_redirect: false
expect_mac: true
expect_det: true
# DET without the MAC services. csm.c compiles the Det_ReportError()
# call whenever WOLFSSL_AUTOSAR_DET is defined, so a build that does
# not define the symbol fails to link -- which this configuration did,
# because test.c had its definition behind CMAC as well. det_test
# needs a service that reports a development error to drive it, and
# only the MAC services do, so it does not run here; the point of the
# entry is that the link succeeds.
- name: det-nocmac
config: >-
--enable-autosar
--enable-static --disable-shared
CPPFLAGS=-DWOLFSSL_AUTOSAR_DET
expect_redirect: false
expect_no_det_test: true
# Key redirection together with the MAC services. That combination
# cannot tell CRYPTO_KE_CIPHER_KEY from CRYPTO_KE_MAC_KEY -- both are
# element 0x01 and redirection pins one slot for every service -- so
# crypto.c refuses it at build time unless the integrator says they
# only use one of the two services. This entry is that case, and the
# step below asserts the refusal itself.
#
# Neither entry above covered redirection with CMAC, which is how the
# ambiguity went unnoticed: keysep_test failed there and nothing ran
# it.
- name: key-redirection-cmac
config: >-
--enable-autosar --enable-autosar-cmac
CPPFLAGS="-DREDIRECTION_CONFIG=0x03
-DREDIRECTION_IN1_KEYID=1 -DREDIRECTION_IN1_KEYELMID=0x01
-DREDIRECTION_IN2_KEYID=4 -DREDIRECTION_IN2_KEYELMID=0x05
-DWOLFSSL_AUTOSAR_ALLOW_AMBIGUOUS_KEY_ELEMENT"
expect_redirect: true
expect_mac: true
expect_ambiguous_opt_out: true
# The escape hatch from the ambiguous-key-element refusal. It is a
# security-relevant default being turned off, so it gets its own
# entry rather than being trusted to compile: keysep_test drops the
# refusal assertion here and must still pass on the named-slot path,
# which is what the ECU being told to use it depends on.
- name: ambiguous-key
config: >-
--enable-autosar --enable-autosar-cmac
CPPFLAGS=-DWOLFSSL_AUTOSAR_ALLOW_AMBIGUOUS_KEY_ELEMENT
expect_redirect: false
expect_mac: true
steps:
- uses: actions/checkout@v5
name: Checkout wolfSSL
- name: Autogen
run: ./autogen.sh
# --enable-autosar-cmac is an add-on, not the default. Enabling it
# without --enable-autosar has to be an error rather than a quiet no-op.
#
# In tree, and before the real configure below. AC_MSG_ERROR exits before
# AC_OUTPUT, so this writes no Makefile, options.h or config.status for
# the build to trip over. Doing it afterwards out of tree does not work:
# automake's VPATH guard rejects a source directory that already has a
# config.status, so the log would carry that error instead of the one
# being asserted.
- name: Assert autosar-cmac requires autosar
if: ${{ matrix.expect_mac }}
run: |
if ./configure --enable-autosar-cmac > cmac-alone.log 2>&1; then
echo "--enable-autosar-cmac configured without --enable-autosar" >&2
exit 1
fi
grep -q 'requires --enable-autosar' cmac-alone.log
- name: Build the AUTOSAR port test
run: |
./configure ${{ matrix.config }}
make -j$(nproc) wolfcrypt/src/port/autosar/test.test
- name: Run the AUTOSAR port test
run: |
set -o pipefail
./wolfcrypt/src/port/autosar/test.test | tee autosar-test.log
# A build that silently loses the redirection macros still passes every
# test above, because redirect_test is simply not compiled in -- which is
# how the feature stayed broken. Assert it actually ran, so this entry
# cannot go green without having exercised redirection.
- name: Assert redirect_test ran
if: ${{ matrix.expect_redirect }}
run: grep -qx 'redirect_test \.\.\. pass' autosar-test.log
# The converse: the default entry must not be silently picking up a
# redirection config from somewhere, or it stops covering the scan path.
- name: Assert redirect_test did not run
if: ${{ !matrix.expect_redirect }}
run: |
if grep -q 'redirect_test' autosar-test.log; then
echo "redirect_test ran in the default config" >&2
exit 1
fi
# Same reasoning as the redirect assertion: mac_test is compiled in only
# when the option took effect, so its absence would pass silently.
- name: Assert mac_test ran
if: ${{ matrix.expect_mac }}
run: grep -qx 'mac_test \.\.\. pass' autosar-test.log
# Same reasoning again: devid_test is absent without --enable-cryptocb,
# so its silence would look like success.
- name: Assert devid_test ran
if: ${{ matrix.expect_devid }}
run: grep -qx 'devid_test \.\.\. pass' autosar-test.log
- name: Assert keyhandle_test ran
if: ${{ matrix.expect_keyhandle }}
run: grep -qx 'keyhandle_test \.\.\. pass' autosar-test.log
# A MAC job whose key lives in the device. Compiled in only with the key
# handle and MAC options together, so its silence would look like
# success -- and it is the case that proves the MAC services can use a
# key they never see.
- name: Assert machandle_test ran
if: ${{ matrix.expect_keyhandle }}
run: grep -qx 'machandle_test \.\.\. pass' autosar-test.log
# reinit_test runs everywhere, but only observes contexts actually being
# freed where the device is told about frees.
- name: Assert reinit_test ran
run: grep -qx 'reinit_test \.\.\. pass' autosar-test.log
# cancel_test is the counterpart: a re-init is refused while a job is
# open, so an abandoned job has to be cancellable or the configuration
# could never be changed again.
- name: Assert cancel_test ran
run: grep -qx 'cancel_test \.\.\. pass' autosar-test.log
# The threaded case. Single-threaded builds compile it out, and none of
# these entries are single-threaded, so silence here means it stopped
# being built rather than that it had nothing to do.
- name: Assert gate_test ran
run: grep -qx 'gate_test \.\.\. pass' autosar-test.log
- name: Assert det_test ran
if: ${{ matrix.expect_det }}
run: grep -qx 'det_test \.\.\. pass' autosar-test.log
# The DET-without-CMAC entry exists for the link, so det_test cannot run
# there. Assert that rather than leaving the entry asserting nothing.
- name: Assert det_test did not run
if: ${{ matrix.expect_no_det_test }}
run: |
if grep -q 'det_test' autosar-test.log; then
echo "det_test ran without the MAC services" >&2
exit 1
fi
# keysep_test provisions a cipher key and a MAC key at the same time,
# which is the case the shared key element ID 0x01 used to get wrong: the
# MAC job took whichever slot came first. It needs both services, so it
# is compiled in exactly where mac_test is.
# The opt-out exists because the combination is otherwise refused. Assert
# that refusal, or the entry above would silently become the only thing
# covering redirection with CMAC while the guard rotted.
- name: Assert redirection with CMAC is refused without the opt-out
if: ${{ matrix.expect_ambiguous_opt_out }}
run: |
# Touch the source first. The step above already built this target,
# so make would otherwise report it up to date and exit 0 without
# recompiling anything -- which reads as "the refusal did not fire"
# and fails the job on a build that never happened.
#
# CPPFLAGS on the command line replaces what configure recorded,
# which for this entry is these same defines plus the opt-out. So
# this rebuilds crypto.c with the opt-out removed and nothing else
# changed.
touch wolfcrypt/src/port/autosar/crypto.c
set +e
make wolfcrypt/src/port/autosar/test.test \
CPPFLAGS="-DREDIRECTION_CONFIG=0x03 \
-DREDIRECTION_IN1_KEYID=1 -DREDIRECTION_IN1_KEYELMID=0x01 \
-DREDIRECTION_IN2_KEYID=4 -DREDIRECTION_IN2_KEYELMID=0x05" \
> ambig.log 2>&1
rc=$?
set -e
if [ "$rc" -eq 0 ]; then
echo "redirection + CMAC built without the opt-out" >&2
exit 1
fi
grep -q 'cannot tell a cipher key from a MAC key' ambig.log
# Leave the tree as the entry configured it, for any step after this.
touch wolfcrypt/src/port/autosar/crypto.c
make wolfcrypt/src/port/autosar/test.test > /dev/null
- name: Assert keysep_test ran
if: ${{ matrix.expect_mac }}
run: grep -qx 'keysep_test \.\.\. pass' autosar-test.log
- name: Print errors
if: ${{ failure() }}
run: |
if [ -f config.log ] ; then
tail -n 100 config.log
fi
autosar_cmake:
name: AUTOSAR CMake build and link
if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }}
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- uses: actions/checkout@v5
name: Checkout wolfSSL
- name: Configure and build with WOLFSSL_AUTOSAR=yes
run: |
cmake -S . -B build_autosar -DWOLFSSL_AUTOSAR=yes \
-DBUILD_SHARED_LIBS=ON -DWOLFSSL_EXAMPLES=no \
-DWOLFSSL_CRYPT_TESTS=no
cmake --build build_autosar -j$(nproc)
# The MAC services have their own CMake logic -- WOLFSSL_AUTOSAR_CMAC
# implies WOLFSSL_CMAC and WOLFSSL_AES_DIRECT, and that implication runs
# after the options are read -- and every CMAC entry in the matrix above
# is Autotools, so without this a regression in the CMake path reaches
# nobody until an integrator hits it.
- name: Configure and build with WOLFSSL_AUTOSAR_CMAC=yes
run: |
cmake -S . -B build_autosar_cmac -DWOLFSSL_AUTOSAR=yes \
-DWOLFSSL_AUTOSAR_CMAC=yes -DBUILD_SHARED_LIBS=ON \
-DWOLFSSL_EXAMPLES=no -DWOLFSSL_CRYPT_TESTS=no
cmake --build build_autosar_cmac -j$(nproc)
# The implication is the point: asking for the MAC services alone has to
# pull in the wolfCrypt pieces they call, or every MAC job fails at run
# time in a build that looks configured correctly.
- name: Assert the CMAC implication reached options.h
run: |
for d in WOLFSSL_AUTOSAR_CMAC WOLFSSL_CMAC WOLFSSL_AES_DIRECT ; do
grep -q "define $d" build_autosar_cmac/wolfssl/options.h || {
echo "$d missing from the CMake AUTOSAR CMAC build" >&2
exit 1
}
done
- name: Link a MAC application against the AUTOSAR API
run: |
cat > cmac_link_probe.c <<'EOF'
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/port/autosar/Csm.h>
int main(void)
{
unsigned char mac[16];
unsigned int macSz = (unsigned int)sizeof(mac);
Csm_Init(NULL);
(void)Csm_MacGenerate(1u, CRYPTO_OPERATIONMODE_SINGLECALL,
(const unsigned char*)"msg", 3u, mac, &macSz);
return 0;
}
EOF
cc -o cmac_link_probe cmac_link_probe.c \
-I. -Ibuild_autosar_cmac -Lbuild_autosar_cmac -lwolfssl
LD_LIBRARY_PATH=build_autosar_cmac ./cmac_link_probe
# And the prerequisite the option carries: the MAC services are an
# add-on, so asking for them without the port has to fail at configure
# time rather than produce a library whose Csm_Mac* calls do not link.
- name: Assert WOLFSSL_AUTOSAR_CMAC requires WOLFSSL_AUTOSAR
run: |
if cmake -S . -B build_cmac_alone -DWOLFSSL_AUTOSAR_CMAC=yes \
-DWOLFSSL_EXAMPLES=no -DWOLFSSL_CRYPT_TESTS=no \
> cmac_alone.log 2>&1 ; then
echo "WOLFSSL_AUTOSAR_CMAC configured without WOLFSSL_AUTOSAR" >&2
exit 1
fi
grep -q 'requires WOLFSSL_AUTOSAR' cmac_alone.log
# The option used to append only -DWOLFSSL_AUTOSAR, never the port
# sources, so WOLFSSL_AUTOSAR reached options.h while csm.c, cryif.c and
# crypto.c went uncompiled: an application's Csm_* calls compiled against
# Csm.h and then failed to link. Linking one here is the assertion --
# grepping the source list would not catch a future regression in which
# the files build but the symbols do not get exported.
- name: Link an application against the AUTOSAR API
run: |
cat > csm_link_probe.c <<'EOF'
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/port/autosar/Csm.h>
int main(void) { Csm_Init(NULL); return 0; }
EOF
cc -o csm_link_probe csm_link_probe.c \
-I. -Ibuild_autosar -Lbuild_autosar -lwolfssl
LD_LIBRARY_PATH=build_autosar ./csm_link_probe
# The other branch of the CMake source selection: a user-settings build
# takes WOLFSSL_AUTOSAR from user_settings.h, where CMake cannot see it,
# so the source list keys on WOLFSSL_USER_SETTINGS as well. Both jobs
# above pass WOLFSSL_AUTOSAR=yes on the command line and would not
# notice that branch breaking -- which is how an ECU build came to link
# against Csm.h with nothing behind it. The port is named ONLY in
# user_settings.h here, on purpose.
- name: Link an application against a user-settings CMake build
run: |
mkdir -p us_autosar
{ cat examples/configs/user_settings_all.h ; \
echo '#define WOLFSSL_AUTOSAR' ; \
echo '#define WOLFSSL_AUTOSAR_CMAC' ; \
} > us_autosar/user_settings.h
# The include path has to reach the assembler too, not just the C
# compiler: the SP assembly sources run through the preprocessor and
# include settings.h, which includes "user_settings.h", and
# CMAKE_C_FLAGS does not apply to the ASM language. Without this the
# build fails on sp_x86_64_asm.S with "user_settings.h: No such file
# or directory" -- which is worth knowing for a real user-settings
# CMake build, not just for this probe.
cmake -S . -B build_us -DWOLFSSL_USER_SETTINGS=yes \
-DWOLFSSL_EXAMPLES=no -DWOLFSSL_CRYPT_TESTS=no \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_C_FLAGS="-I$PWD/us_autosar" \
-DCMAKE_ASM_FLAGS="-I$PWD/us_autosar"
cmake --build build_us -j$(nproc)
cat > us_probe.c <<'EOF'
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/port/autosar/Csm.h>
int main(void)
{
Csm_ConfigType cfg = WOLFSSL_CSM_CONFIG_DEFAULT;
unsigned char mac[16];
unsigned int macSz = (unsigned int)sizeof(mac);
Csm_Init(&cfg);
(void)Csm_MacGenerate(1u, CRYPTO_OPERATIONMODE_SINGLECALL,
(const unsigned char*)"msg", 3u, mac, &macSz);
return (Csm_CancelJob(1u, CRYPTO_OPERATIONMODE_FINISH) == E_OK)
? 1 : 0;
}
EOF
# Shared, like the probes above: a static libwolfssl.a would make
# this link line carry the library's own dependencies -- libm, for
# DiscreteLogWorkFactor()'s pow() and log() -- which says nothing
# about the AUTOSAR sources being in the build.
cc -o us_probe us_probe.c -DWOLFSSL_USER_SETTINGS \
-Ius_autosar -I. -Ibuild_us -Lbuild_us -lwolfssl
LD_LIBRARY_PATH=build_us ./us_probe
# The converse: a default build must not compile the port.
- name: Assert the port stays out of a default build
run: |
cmake -S . -B build_default -DWOLFSSL_EXAMPLES=no \
-DWOLFSSL_CRYPT_TESTS=no > /dev/null
if grep -q 'port/autosar' \
build_default/CMakeFiles/wolfssl.dir/build.make; then
echo "autosar port compiled without WOLFSSL_AUTOSAR" >&2
exit 1
fi