Branch data Line data Source code
1 : : /* SPDX-FileCopyrightText: Copyright 2026 Cozens Software Solutions Limited
2 : : * SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0 OR LicenseRef-PolyForm-Internal-Use-1.0.0 OR LicenseRef-COSOSO-Commercial
3 : : */
4 : :
5 : : #include "SolidSyslogWolfSslSettings.h"
6 : :
7 : : #include <stdbool.h>
8 : : #include <stdint.h>
9 : :
10 : : #include "SolidSyslogWolfSslAesGcmPolicyPrivate.h"
11 : : #include "SolidSyslogSecurityPolicyDefinition.h"
12 : :
13 : : /* The Xilinx AF_ALG port reads and writes WC_AES_BLOCK_SIZE bytes beyond the
14 : : * body, which here is the record's trailer. The definitions are withheld on
15 : : * that build, so the link names what is missing. */
16 : : #ifndef WOLFSSL_AFALG_XILINX_AES
17 : :
18 : : #include <wolfssl/wolfcrypt/aes.h>
19 : : #include <wolfssl/wolfcrypt/error-crypt.h>
20 : : #include <wolfssl/wolfcrypt/types.h>
21 : :
22 : : /* One AES-256-GCM seal with a transient wolfCrypt context: the body is
23 : : * encrypted in place, the header authenticated, and the tag written after the
24 : : * nonce already in the trailer. Any step failing is one fault to the caller;
25 : : * the context is freed whenever it was initialised. */
26 : 44 : bool SolidSyslogWolfSslAesGcmPolicy_GcmEncrypt(const struct SolidSyslogSecurityRecord* record, const uint8_t* key)
27 : : {
28 : 44 : uint8_t* body = &record->Content[record->HeaderLength];
29 : 44 : uint16_t bodyLength = (uint16_t) (record->ContentLength - record->HeaderLength);
30 : :
31 : : Aes aes;
32 : 44 : bool ok = false;
33 [ + + ]: 44 : if (wc_AesInit(&aes, NULL, INVALID_DEVID) == 0)
34 : : {
35 [ + + + + ]: 82 : ok = (wc_AesGcmSetKey(&aes, key, SOLIDSYSLOG_WOLFSSL_AES_GCM_POLICY_KEY_SIZE) == 0) &&
36 : 40 : (wc_AesGcmEncrypt(
37 : : &aes,
38 : : body,
39 : : body,
40 : : bodyLength,
41 : 40 : record->Trailer,
42 : : SOLIDSYSLOG_WOLFSSL_AES_GCM_POLICY_NONCE_SIZE,
43 : 40 : &record->Trailer[SOLIDSYSLOG_WOLFSSL_AES_GCM_POLICY_NONCE_SIZE],
44 : : SOLIDSYSLOG_WOLFSSL_AES_GCM_POLICY_TAG_SIZE,
45 : 40 : record->Content,
46 : 40 : record->HeaderLength
47 : : ) == 0);
48 : 42 : wc_AesFree(&aes);
49 : : }
50 : 44 : return ok;
51 : : }
52 : :
53 : : /* The verdict comes from wc_AesGcmDecrypt's return code: 0 is authentic,
54 : : * AES_GCM_AUTH_E is tamper or wrong key (the expected rejection - silent, like
55 : : * the HMAC verify), anything else a genuine wolfCrypt error, which reaches no
56 : : * verdict. */
57 : 26 : enum SolidSyslogSecurityPolicyOpenResult SolidSyslogWolfSslAesGcmPolicy_GcmDecrypt(
58 : : const struct SolidSyslogSecurityRecord* record,
59 : : const uint8_t* key
60 : : )
61 : : {
62 : 26 : uint8_t* body = &record->Content[record->HeaderLength];
63 : 26 : uint16_t bodyLength = (uint16_t) (record->ContentLength - record->HeaderLength);
64 : :
65 : : Aes aes;
66 : 26 : enum SolidSyslogSecurityPolicyOpenResult result = SOLIDSYSLOG_SECURITY_POLICY_OPEN_COULD_NOT_RUN;
67 [ + + ]: 26 : if (wc_AesInit(&aes, NULL, INVALID_DEVID) == 0)
68 : : {
69 [ + + ]: 24 : if (wc_AesGcmSetKey(&aes, key, SOLIDSYSLOG_WOLFSSL_AES_GCM_POLICY_KEY_SIZE) == 0)
70 : : {
71 : 22 : int verdict = wc_AesGcmDecrypt(
72 : : &aes,
73 : : body,
74 : : body,
75 : : bodyLength,
76 : 22 : record->Trailer,
77 : : SOLIDSYSLOG_WOLFSSL_AES_GCM_POLICY_NONCE_SIZE,
78 : 22 : &record->Trailer[SOLIDSYSLOG_WOLFSSL_AES_GCM_POLICY_NONCE_SIZE],
79 : : SOLIDSYSLOG_WOLFSSL_AES_GCM_POLICY_TAG_SIZE,
80 : 22 : record->Content,
81 : 22 : record->HeaderLength
82 : : );
83 [ + + ]: 22 : if (verdict == 0)
84 : : {
85 : 7 : result = SOLIDSYSLOG_SECURITY_POLICY_OPEN_OPENED;
86 : : }
87 [ + + ]: 15 : else if (verdict == AES_GCM_AUTH_E)
88 : : {
89 : 14 : result = SOLIDSYSLOG_SECURITY_POLICY_OPEN_REJECTED;
90 : : }
91 : : else
92 : : {
93 : : /* Genuine wolfCrypt failure - no verdict. */
94 : : }
95 : : }
96 : 24 : wc_AesFree(&aes);
97 : : }
98 : 26 : return result;
99 : : }
100 : :
101 : : #endif /* WOLFSSL_AFALG_XILINX_AES */
|