iso14229 0.9.0
ISO14229-1 (UDS) C Library
Loading...
Searching...
No Matches
client.c
Go to the documentation of this file.
1/**
2 * @file examples/linux_server_0x27/client.c
3 * @brief UDS client demonstrating Security Access (0x27)
4 */
5#include "iso14229.h"
6#include <stdint.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <mbedtls/config.h>
11#include <mbedtls/platform.h>
12#include <mbedtls/entropy.h>
13#include <mbedtls/ctr_drbg.h>
14#include <mbedtls/pk.h>
15#include <mbedtls/rsa.h>
16#include <mbedtls/sha256.h>
17
18typedef struct {
19 enum {
20 Step_0_RequestSeed,
21 Step_1_ReceiveSeed,
22 Step_2_SendKey,
23 Step_3_ReceiveKeyResponse,
24 Step_DONE,
25 } step;
26 UDSErr_t err;
27 uint8_t seed[256];
28 size_t seed_len;
30
31static int sign(const uint8_t *seed, size_t seed_len, uint8_t *key, size_t key_len) {
32 int ret = 0;
33 mbedtls_pk_context pk;
34 mbedtls_entropy_context entropy;
35 mbedtls_ctr_drbg_context ctr_drbg;
36 mbedtls_entropy_init(&entropy);
37 mbedtls_ctr_drbg_init(&ctr_drbg);
38 const char *pers = "rsa_sign";
39 mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *)pers,
40 strlen(pers));
41
42 mbedtls_pk_init(&pk);
43
44 const char *private_key_pem = "private_key.pem";
45
46 if (mbedtls_pk_parse_keyfile(&pk, private_key_pem, NULL) != 0) {
47 mbedtls_printf("Failed to parse private key\n");
48 ret = -1;
49 goto exit;
50 }
51
52 // Verify that the loaded key is an RSA key
53 if (mbedtls_pk_get_type(&pk) != MBEDTLS_PK_RSA) {
54 mbedtls_printf("Loaded key is not an RSA key\n");
55 ret = -1;
56 goto exit;
57 }
58
59 mbedtls_rsa_context *rsa = mbedtls_pk_rsa(pk);
60
61 // Allocate buffer for the signature
62 size_t sig_len = mbedtls_rsa_get_len(rsa);
63 if (sig_len != key_len) {
64 fprintf(stderr, "sig_len: %zu != %zu\n", sig_len, key_len);
65 ret = -1;
66 goto exit;
67 }
68
69 // Perform RSA signing operation
70 if (mbedtls_rsa_rsassa_pkcs1_v15_sign(rsa, mbedtls_ctr_drbg_random, &ctr_drbg,
71 MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA256, seed_len, seed,
72 key) != 0) {
73 mbedtls_printf("Failed to sign data\n");
74 ret = -1;
75 goto exit;
76 }
77
78 // 'key' now contains the RSA signature
79
80exit:
81 mbedtls_rsa_free(rsa);
82 mbedtls_ctr_drbg_free(&ctr_drbg);
83 mbedtls_entropy_free(&entropy);
84 return ret;
85}
86
87UDSErr_t fn(UDSClient_t *client, UDSEvent_t evt, void *ev_data) {
89 if (evt != UDS_EVT_Poll) {
90 UDS_LOGI(__FILE__, "%s (%d)", UDSEventToStr(evt), evt);
91 }
92 if (UDS_EVT_Err == evt) {
93 UDS_LOGE(__FILE__, "Exiting on step %d with error: %s", c->step,
94 UDSErrToStr(*(UDSErr_t *)ev_data));
95 c->err = *(UDSErr_t *)ev_data;
96 c->step = Step_DONE;
97 }
98 switch (c->step) {
99 case Step_0_RequestSeed: {
100 c->err = UDSSendSecurityAccess(client, 3, NULL, 0);
101 if (c->err) {
102 UDS_LOGE(__FILE__, "UDSSendSecurityAccess failed with err: %s", UDSErrToStr(c->err));
103 c->step = Step_DONE;
104 }
105 c->step = Step_1_ReceiveSeed;
106 break;
107 }
108 case Step_1_ReceiveSeed: {
109 if (UDS_EVT_ResponseReceived == evt) {
110 struct SecurityAccessResponse sar = {0};
111 c->err = UDSUnpackSecurityAccessResponse(client, &sar);
112 if (c->err) {
113 UDS_LOGE(__FILE__, "UDSUnpackSecurityAccessResponse failed with err: %s",
114 UDSErrToStr(c->err));
115 c->step = Step_DONE;
116 break;
117 }
118
119 printf("seed: ");
120 for (int i = 0; i < sar.securitySeedLength; i++) {
121 printf("%02X ", sar.securitySeed[i]);
122 }
123 printf("\n");
124
125 // Check if all bytes in the seed are 0
126 bool all_zero = true;
127 for (int i = 0; i < sar.securitySeedLength; i++) {
128 if (sar.securitySeed[i] != 0) {
129 all_zero = false;
130 break;
131 }
132 }
133
134 if (all_zero) {
135 UDS_LOGI(__FILE__, "seed is all zero, already unlocked");
136 c->step = Step_DONE;
137 break;
138 }
139
140 // Store seed for later use
141 memcpy(c->seed, sar.securitySeed, sar.securitySeedLength);
142 c->seed_len = sar.securitySeedLength;
143 c->step = Step_2_SendKey;
144 }
145 break;
146 }
147 case Step_2_SendKey: {
148 uint8_t key[512] = {0};
149 if (sign(c->seed, c->seed_len, key, sizeof(key))) {
150 UDS_LOGE(__FILE__, "sign failed");
151 c->err = UDS_FAIL;
152 c->step = Step_DONE;
153 break;
154 }
155
156 c->err = UDSSendSecurityAccess(client, 4, key, sizeof(key));
157 if (c->err) {
158 UDS_LOGE(__FILE__, "UDSSendSecurityAccess failed with err: %s", UDSErrToStr(c->err));
159 c->step = Step_DONE;
160 break;
161 }
162 c->step = Step_3_ReceiveKeyResponse;
163 break;
164 }
165 case Step_3_ReceiveKeyResponse: {
166 if (UDS_EVT_ResponseReceived == evt) {
167 UDS_LOGI(__FILE__, "Security access unlocked");
168 c->step = Step_DONE;
169 }
170 break;
171 }
172
173 default:
174 break;
175 }
176 return UDS_OK;
177}
178
179int main(int ac, char **av) {
180 UDSClient_t client;
181#if defined(UDS_TP_ISOTP_SOCK)
183 if (UDSTpIsoTpSockInitClient(&tp, "vcan0", 0x7E8, 0x7E0, 0x7DF)) {
184 UDS_LOGE(__FILE__, "UDSTpIsoTpSockInitClient failed");
185 exit(-1);
186 }
187#elif defined(UDS_TP_ISOTP_C_SOCKETCAN)
188 UDSTpISOTpC_t tp;
189 if (UDSTpISOTpCInit((UDSTpISOTpC_t *)&tp, "vcan0", 0x7E8, 0x7E0, 0x7DF, 0x7FF)) {
190 UDS_LOGE(__FILE__, "UDSTpISOTpCInit failed");
191 exit(-1);
192 }
193#else
194#error "no transport defined"
195#endif
196
197 if (UDSClientInit(&client)) {
198 exit(-1);
199 }
200
201 client.tp = (UDSTp_t *)&tp;
202 client.fn = fn;
203
204 SequenceContext_t ctx = {0};
205 client.fn_data = &ctx;
206
207 UDS_LOGI(__FILE__, "polling");
208 while (ctx.step != Step_DONE) {
209 UDSClientPoll(&client);
210 }
211
212 return ctx.err;
213}
ISO14229-1 (UDS) library.
UDSEvent_t
UDS events.
Definition iso14229.h:298
@ UDS_EVT_Poll
Definition iso14229.h:326
@ UDS_EVT_ResponseReceived
Definition iso14229.h:328
@ UDS_EVT_Err
Definition iso14229.h:299
Security access response structure.
Definition iso14229.h:753
uint16_t securitySeedLength
Definition iso14229.h:756
const uint8_t * securitySeed
Definition iso14229.h:755
UDS client structure.
Definition iso14229.h:729
int(* fn)(struct UDSClient *client, UDSEvent_t evt, void *ev_data)
Definition iso14229.h:741
void * fn_data
Definition iso14229.h:742
UDSTp_t * tp
Definition iso14229.h:732
UDS Transport layer.
Definition iso14229.h:254