Coverage Report

Created: 2026-07-25 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/nsmd/libnsm/debug-token.c
Line
Count
Source
1
/*
2
 * SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION &
3
 * AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 * http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
#include "debug-token.h"
19
20
#include <endian.h>
21
#include <string.h>
22
23
int decode_nsm_query_token_parameters_req(
24
    const struct nsm_msg *msg, size_t msg_len,
25
    enum nsm_debug_token_opcode *token_opcode)
26
0
{
27
0
  if (msg == NULL || token_opcode == NULL) {
28
0
    return NSM_SW_ERROR_NULL;
29
0
  }
30
0
  if (msg_len < sizeof(struct nsm_msg_hdr) +
31
0
        sizeof(struct nsm_query_token_parameters_req)) {
32
0
    return NSM_SW_ERROR_LENGTH;
33
0
  }
34
35
0
  struct nsm_query_token_parameters_req *request =
36
0
      (struct nsm_query_token_parameters_req *)msg->payload;
37
0
  if (request->hdr.data_size < sizeof(request->token_opcode)) {
38
0
    return NSM_SW_ERROR_DATA;
39
0
  }
40
0
  *token_opcode = request->token_opcode;
41
42
0
  return NSM_SW_SUCCESS;
43
0
}
44
45
int encode_nsm_query_token_parameters_req(
46
    uint8_t instance_id, enum nsm_debug_token_opcode token_opcode,
47
    struct nsm_msg *msg)
48
0
{
49
0
  if (msg == NULL) {
50
0
    return NSM_SW_ERROR_NULL;
51
0
  }
52
0
  if (token_opcode != NSM_DEBUG_TOKEN_OPCODE_RMCS &&
53
0
      token_opcode != NSM_DEBUG_TOKEN_OPCODE_RMDT &&
54
0
      token_opcode != NSM_DEBUG_TOKEN_OPCODE_CRCS &&
55
0
      token_opcode != NSM_DEBUG_TOKEN_OPCODE_CRDT &&
56
0
      token_opcode != NSM_DEBUG_TOKEN_OPCODE_LINKX_FRC) {
57
0
    return NSM_SW_ERROR_DATA;
58
0
  }
59
60
0
  struct nsm_header_info header = {0};
61
0
  header.nsm_msg_type = NSM_REQUEST;
62
0
  header.instance_id = instance_id;
63
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
64
65
0
  uint8_t rc = pack_nsm_header(&header, &msg->hdr);
66
0
  if (rc != NSM_SW_SUCCESS) {
67
0
    return rc;
68
0
  }
69
70
0
  struct nsm_query_token_parameters_req *request =
71
0
      (struct nsm_query_token_parameters_req *)msg->payload;
72
0
  request->hdr.command = NSM_QUERY_TOKEN_PARAMETERS;
73
0
  request->hdr.data_size = 1;
74
0
  request->token_opcode = token_opcode;
75
76
0
  return NSM_SW_SUCCESS;
77
0
}
78
79
int decode_nsm_query_token_parameters_resp(
80
    const struct nsm_msg *msg, size_t msg_len, uint8_t *cc,
81
    uint16_t *reason_code, struct nsm_debug_token_request *token_request)
82
0
{
83
0
  if (msg == NULL || token_request == NULL) {
84
0
    return NSM_SW_ERROR_NULL;
85
0
  }
86
87
0
  int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code);
88
0
  if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) {
89
0
    return rc;
90
0
  }
91
92
0
  if (msg_len < sizeof(struct nsm_msg_hdr) +
93
0
        sizeof(struct nsm_query_token_parameters_resp)) {
94
0
    return NSM_SW_ERROR_LENGTH;
95
0
  }
96
97
0
  struct nsm_query_token_parameters_resp *resp =
98
0
      (struct nsm_query_token_parameters_resp *)msg->payload;
99
0
  if (resp->token_request.token_request_size !=
100
0
      sizeof(struct nsm_debug_token_request)) {
101
0
    return NSM_SW_ERROR_DATA;
102
0
  }
103
0
  *token_request = resp->token_request;
104
105
0
  return NSM_SW_SUCCESS;
106
0
}
107
108
int encode_nsm_query_token_parameters_resp(
109
    uint8_t instance_id, uint8_t cc, uint16_t reason_code,
110
    struct nsm_debug_token_request *token_request, struct nsm_msg *msg)
111
0
{
112
0
  if (msg == NULL) {
113
0
    return NSM_SW_ERROR_NULL;
114
0
  }
115
116
0
  struct nsm_header_info header = {0};
117
0
  header.nsm_msg_type = NSM_RESPONSE;
118
0
  header.instance_id = instance_id;
119
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
120
121
0
  uint8_t rc = pack_nsm_header(&header, &msg->hdr);
122
0
  if (rc != NSM_SW_SUCCESS) {
123
0
    return rc;
124
0
  }
125
126
0
  if (cc != NSM_SUCCESS) {
127
0
    return encode_reason_code(cc, reason_code,
128
0
            NSM_QUERY_TOKEN_PARAMETERS, msg);
129
0
  }
130
131
0
  struct nsm_query_token_parameters_resp *response =
132
0
      (struct nsm_query_token_parameters_resp *)msg->payload;
133
0
  response->hdr.command = NSM_QUERY_TOKEN_PARAMETERS;
134
0
  response->hdr.completion_code = cc;
135
0
  response->hdr.data_size =
136
0
      htole16(sizeof(struct nsm_debug_token_request));
137
0
  response->token_request = *token_request;
138
139
0
  return NSM_SW_SUCCESS;
140
0
}
141
142
int decode_nsm_provide_token_req(const struct nsm_msg *msg, size_t msg_len,
143
         uint8_t *token_data, uint8_t *token_data_len)
144
0
{
145
0
  if (msg == NULL || token_data == NULL || token_data_len == NULL) {
146
0
    return NSM_SW_ERROR_NULL;
147
0
  }
148
0
  if (msg_len <
149
0
      sizeof(struct nsm_msg_hdr) + sizeof(struct nsm_provide_token_req)) {
150
0
    return NSM_SW_ERROR_LENGTH;
151
0
  }
152
153
0
  struct nsm_provide_token_req *request =
154
0
      (struct nsm_provide_token_req *)msg->payload;
155
0
  if (request->hdr.data_size == 0) {
156
0
    return NSM_SW_ERROR_DATA;
157
0
  }
158
0
  memcpy(token_data, request->token_data, request->hdr.data_size);
159
0
  *token_data_len = request->hdr.data_size;
160
161
0
  return NSM_SW_SUCCESS;
162
0
}
163
164
int encode_nsm_provide_token_req(uint8_t instance_id, const uint8_t *token_data,
165
         const uint16_t token_data_len,
166
         struct nsm_msg *msg)
167
0
{
168
0
  if (msg == NULL || token_data == NULL) {
169
0
    return NSM_SW_ERROR_NULL;
170
0
  }
171
0
  if (token_data_len == 0) {
172
0
    return NSM_SW_ERROR_DATA;
173
0
  }
174
175
0
  struct nsm_header_info header = {0};
176
0
  header.nsm_msg_type = NSM_REQUEST;
177
0
  header.instance_id = instance_id;
178
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
179
180
0
  uint8_t rc = pack_nsm_header_v2(&header, &msg->hdr);
181
0
  if (rc != NSM_SW_SUCCESS) {
182
0
    return rc;
183
0
  }
184
185
0
  struct nsm_provide_token_req *request =
186
0
      (struct nsm_provide_token_req *)msg->payload;
187
0
  request->hdr.command = NSM_PROVIDE_TOKEN;
188
0
  request->hdr.data_size = htole16(token_data_len);
189
0
  memcpy(request->token_data, token_data, token_data_len);
190
191
0
  return NSM_SW_SUCCESS;
192
0
}
193
194
int decode_nsm_provide_token_resp(const struct nsm_msg *msg, size_t msg_len,
195
          uint8_t *cc, uint16_t *reason_code)
196
0
{
197
0
  if (msg == NULL || cc == NULL || reason_code == NULL) {
198
0
    return NSM_SW_ERROR_NULL;
199
0
  }
200
201
0
  int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code);
202
0
  if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) {
203
0
    return rc;
204
0
  }
205
206
0
  if (msg_len <
207
0
      sizeof(struct nsm_msg_hdr) + sizeof(nsm_provide_token_resp)) {
208
0
    return NSM_SW_ERROR_LENGTH;
209
0
  }
210
211
0
  return NSM_SW_SUCCESS;
212
0
}
213
214
int encode_nsm_provide_token_resp(uint8_t instance_id, uint8_t cc,
215
          uint16_t reason_code, struct nsm_msg *msg)
216
0
{
217
0
  if (msg == NULL) {
218
0
    return NSM_SW_ERROR_NULL;
219
0
  }
220
221
0
  struct nsm_header_info header = {0};
222
0
  header.nsm_msg_type = NSM_RESPONSE;
223
0
  header.instance_id = instance_id;
224
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
225
226
0
  uint8_t rc = pack_nsm_header(&header, &msg->hdr);
227
0
  if (rc != NSM_SW_SUCCESS) {
228
0
    return rc;
229
0
  }
230
231
0
  if (cc != NSM_SUCCESS) {
232
0
    return encode_reason_code(cc, reason_code, NSM_PROVIDE_TOKEN,
233
0
            msg);
234
0
  }
235
236
0
  struct nsm_query_token_parameters_resp *response =
237
0
      (struct nsm_query_token_parameters_resp *)msg->payload;
238
0
  response->hdr.command = NSM_PROVIDE_TOKEN;
239
0
  response->hdr.completion_code = cc;
240
0
  response->hdr.data_size = 0;
241
242
0
  return NSM_SW_SUCCESS;
243
0
}
244
245
int decode_nsm_disable_tokens_req(const struct nsm_msg *msg, size_t msg_len)
246
0
{
247
0
  if (msg == NULL) {
248
0
    return NSM_SW_ERROR_NULL;
249
0
  }
250
0
  if (msg_len <
251
0
      sizeof(struct nsm_msg_hdr) + sizeof(nsm_disable_tokens_req)) {
252
0
    return NSM_SW_ERROR_LENGTH;
253
0
  }
254
255
0
  return NSM_SW_SUCCESS;
256
0
}
257
258
int encode_nsm_disable_tokens_req(uint8_t instance_id, struct nsm_msg *msg)
259
0
{
260
0
  if (msg == NULL) {
261
0
    return NSM_SW_ERROR_NULL;
262
0
  }
263
264
0
  struct nsm_header_info header = {0};
265
0
  header.nsm_msg_type = NSM_REQUEST;
266
0
  header.instance_id = instance_id;
267
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
268
269
0
  uint8_t rc = pack_nsm_header(&header, &msg->hdr);
270
0
  if (rc != NSM_SW_SUCCESS) {
271
0
    return rc;
272
0
  }
273
274
0
  nsm_disable_tokens_req *request =
275
0
      (nsm_disable_tokens_req *)msg->payload;
276
0
  request->command = NSM_DISABLE_TOKENS;
277
0
  request->data_size = 0;
278
279
0
  return NSM_SW_SUCCESS;
280
0
}
281
282
int decode_nsm_disable_tokens_resp(const struct nsm_msg *msg, size_t msg_len,
283
           uint8_t *cc, uint16_t *reason_code)
284
0
{
285
0
  if (msg == NULL || cc == NULL || reason_code == NULL) {
286
0
    return NSM_SW_ERROR_NULL;
287
0
  }
288
289
0
  int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code);
290
0
  if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) {
291
0
    return rc;
292
0
  }
293
294
0
  if (msg_len <
295
0
      sizeof(struct nsm_msg_hdr) + sizeof(nsm_disable_tokens_resp)) {
296
0
    return NSM_SW_ERROR_LENGTH;
297
0
  }
298
299
0
  return NSM_SW_SUCCESS;
300
0
}
301
302
int encode_nsm_disable_tokens_resp(uint8_t instance_id, uint8_t cc,
303
           uint16_t reason_code, struct nsm_msg *msg)
304
0
{
305
0
  if (msg == NULL) {
306
0
    return NSM_SW_ERROR_NULL;
307
0
  }
308
309
0
  struct nsm_header_info header = {0};
310
0
  header.nsm_msg_type = NSM_RESPONSE;
311
0
  header.instance_id = instance_id;
312
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
313
314
0
  uint8_t rc = pack_nsm_header(&header, &msg->hdr);
315
0
  if (rc != NSM_SW_SUCCESS) {
316
0
    return rc;
317
0
  }
318
319
0
  if (cc != NSM_SUCCESS) {
320
0
    return encode_reason_code(cc, reason_code, NSM_DISABLE_TOKENS,
321
0
            msg);
322
0
  }
323
324
0
  struct nsm_query_token_parameters_resp *response =
325
0
      (struct nsm_query_token_parameters_resp *)msg->payload;
326
0
  response->hdr.command = NSM_DISABLE_TOKENS;
327
0
  response->hdr.completion_code = cc;
328
0
  response->hdr.data_size = 0;
329
330
0
  return NSM_SW_SUCCESS;
331
0
}
332
333
int decode_nsm_query_token_status_req(const struct nsm_msg *msg, size_t msg_len,
334
              enum nsm_debug_token_type *token_type)
335
0
{
336
0
  if (msg == NULL || token_type == NULL) {
337
0
    return NSM_SW_ERROR_NULL;
338
0
  }
339
0
  if (msg_len < sizeof(struct nsm_msg_hdr) +
340
0
        sizeof(struct nsm_query_token_status_req)) {
341
0
    return NSM_SW_ERROR_LENGTH;
342
0
  }
343
344
0
  struct nsm_query_token_status_req *request =
345
0
      (struct nsm_query_token_status_req *)msg->payload;
346
0
  if (request->hdr.data_size < sizeof(request->token_type)) {
347
0
    return NSM_SW_ERROR_DATA;
348
0
  }
349
0
  *token_type = request->token_type;
350
351
0
  return NSM_SW_SUCCESS;
352
0
}
353
354
int encode_nsm_query_token_status_req(uint8_t instance_id,
355
              enum nsm_debug_token_type token_type,
356
              struct nsm_msg *msg)
357
0
{
358
0
  if (msg == NULL) {
359
0
    return NSM_SW_ERROR_NULL;
360
0
  }
361
0
  if (token_type != NSM_DEBUG_TOKEN_TYPE_FRC &&
362
0
      token_type != NSM_DEBUG_TOKEN_TYPE_CRCS &&
363
0
      token_type != NSM_DEBUG_TOKEN_TYPE_CRDT &&
364
0
      token_type != NSM_DEBUG_TOKEN_TYPE_DEBUG_FIRMWARE) {
365
0
    return NSM_SW_ERROR_DATA;
366
0
  }
367
368
0
  struct nsm_header_info header = {0};
369
0
  header.nsm_msg_type = NSM_REQUEST;
370
0
  header.instance_id = instance_id;
371
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
372
373
0
  uint8_t rc = pack_nsm_header(&header, &msg->hdr);
374
0
  if (rc != NSM_SW_SUCCESS) {
375
0
    return rc;
376
0
  }
377
378
0
  struct nsm_query_token_status_req *request =
379
0
      (struct nsm_query_token_status_req *)msg->payload;
380
0
  request->hdr.command = NSM_QUERY_TOKEN_STATUS;
381
0
  request->hdr.data_size = 1;
382
0
  request->token_type = token_type;
383
384
0
  return NSM_SW_SUCCESS;
385
0
}
386
387
int decode_nsm_query_token_status_resp(
388
    const struct nsm_msg *msg, size_t msg_len, uint8_t *cc,
389
    uint16_t *reason_code, enum nsm_debug_token_status *status,
390
    enum nsm_debug_token_status_additional_info *additional_info,
391
    enum nsm_debug_token_type *token_type, uint32_t *time_left)
392
0
{
393
0
  if (msg == NULL || status == NULL || additional_info == NULL ||
394
0
      token_type == NULL || time_left == NULL) {
395
0
    return NSM_SW_ERROR_NULL;
396
0
  }
397
398
0
  int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code);
399
0
  if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) {
400
0
    return rc;
401
0
  }
402
403
0
  if (msg_len < sizeof(struct nsm_msg_hdr) +
404
0
        sizeof(struct nsm_query_token_status_resp)) {
405
0
    return NSM_SW_ERROR_LENGTH;
406
0
  }
407
408
0
  struct nsm_query_token_status_resp *resp =
409
0
      (struct nsm_query_token_status_resp *)msg->payload;
410
0
  *status = resp->status;
411
0
  *additional_info = resp->additional_info;
412
0
  *token_type = resp->token_type;
413
0
  *time_left = resp->time_left;
414
415
0
  return NSM_SW_SUCCESS;
416
0
}
417
418
int encode_nsm_query_token_status_resp(
419
    uint8_t instance_id, uint8_t cc, uint16_t reason_code,
420
    enum nsm_debug_token_status status,
421
    enum nsm_debug_token_status_additional_info additional_info,
422
    enum nsm_debug_token_type token_type, uint32_t time_left,
423
    struct nsm_msg *msg)
424
0
{
425
0
  if (msg == NULL) {
426
0
    return NSM_SW_ERROR_NULL;
427
0
  }
428
429
0
  struct nsm_header_info header = {0};
430
0
  header.nsm_msg_type = NSM_RESPONSE;
431
0
  header.instance_id = instance_id;
432
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
433
434
0
  uint8_t rc = pack_nsm_header(&header, &msg->hdr);
435
0
  if (rc != NSM_SW_SUCCESS) {
436
0
    return rc;
437
0
  }
438
439
0
  if (cc != NSM_SUCCESS) {
440
0
    return encode_reason_code(cc, reason_code,
441
0
            NSM_QUERY_TOKEN_STATUS, msg);
442
0
  }
443
444
0
  struct nsm_query_token_status_resp *response =
445
0
      (struct nsm_query_token_status_resp *)msg->payload;
446
0
  response->hdr.command = NSM_QUERY_TOKEN_STATUS;
447
0
  response->hdr.completion_code = cc;
448
0
  response->hdr.data_size =
449
0
      htole16(sizeof(status) + sizeof(additional_info) +
450
0
        sizeof(token_type) + sizeof(time_left));
451
0
  response->status = status;
452
0
  response->additional_info = additional_info;
453
0
  response->token_type = token_type;
454
0
  response->time_left = time_left;
455
456
0
  return NSM_SW_SUCCESS;
457
0
}
458
459
int decode_nsm_query_device_ids_req(const struct nsm_msg *msg, size_t msg_len)
460
0
{
461
0
  if (msg == NULL) {
462
0
    return NSM_SW_ERROR_NULL;
463
0
  }
464
0
  if (msg_len <
465
0
      sizeof(struct nsm_msg_hdr) + sizeof(nsm_query_device_ids_req)) {
466
0
    return NSM_SW_ERROR_LENGTH;
467
0
  }
468
469
0
  return NSM_SW_SUCCESS;
470
0
}
471
472
int encode_nsm_query_device_ids_req(uint8_t instance_id, struct nsm_msg *msg)
473
0
{
474
0
  if (msg == NULL) {
475
0
    return NSM_SW_ERROR_DATA;
476
0
  }
477
478
0
  struct nsm_header_info header = {0};
479
0
  header.nsm_msg_type = NSM_REQUEST;
480
0
  header.instance_id = instance_id;
481
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
482
483
0
  uint8_t rc = pack_nsm_header(&header, &msg->hdr);
484
0
  if (rc != NSM_SW_SUCCESS) {
485
0
    return rc;
486
0
  }
487
488
0
  nsm_query_device_ids_req *request =
489
0
      (nsm_query_device_ids_req *)msg->payload;
490
0
  request->command = NSM_QUERY_DEVICE_IDS;
491
0
  request->data_size = 0;
492
493
0
  return NSM_SW_SUCCESS;
494
0
}
495
496
int decode_nsm_query_device_ids_resp(
497
    const struct nsm_msg *msg, size_t msg_len, uint8_t *cc,
498
    uint16_t *reason_code, uint8_t device_id[NSM_DEBUG_TOKEN_DEVICE_ID_SIZE])
499
0
{
500
0
  if (msg == NULL || cc == NULL || reason_code == NULL) {
501
0
    return NSM_SW_ERROR_NULL;
502
0
  }
503
504
0
  int rc = decode_reason_code_and_cc(msg, msg_len, cc, reason_code);
505
0
  if (rc != NSM_SW_SUCCESS || *cc != NSM_SUCCESS) {
506
0
    return rc;
507
0
  }
508
509
0
  if (msg_len < sizeof(struct nsm_msg_hdr) +
510
0
        sizeof(struct nsm_query_device_ids_resp)) {
511
0
    return NSM_SW_ERROR_DATA;
512
0
  }
513
514
0
  struct nsm_query_device_ids_resp *resp =
515
0
      (struct nsm_query_device_ids_resp *)msg->payload;
516
0
  memcpy(device_id, resp->device_id, NSM_DEBUG_TOKEN_DEVICE_ID_SIZE);
517
518
0
  return NSM_SW_SUCCESS;
519
0
}
520
521
int encode_nsm_query_device_ids_resp(
522
    uint8_t instance_id, uint8_t cc, uint16_t reason_code,
523
    const uint8_t device_id[NSM_DEBUG_TOKEN_DEVICE_ID_SIZE],
524
    struct nsm_msg *msg)
525
0
{
526
0
  if (msg == NULL) {
527
0
    return NSM_SW_ERROR_NULL;
528
0
  }
529
530
0
  struct nsm_header_info header = {0};
531
0
  header.nsm_msg_type = NSM_RESPONSE;
532
0
  header.instance_id = instance_id;
533
0
  header.nvidia_msg_type = NSM_TYPE_DIAGNOSTIC;
534
535
0
  uint8_t rc = pack_nsm_header(&header, &msg->hdr);
536
0
  if (rc != NSM_SW_SUCCESS) {
537
0
    return rc;
538
0
  }
539
540
0
  if (cc != NSM_SUCCESS) {
541
0
    return encode_reason_code(cc, reason_code, NSM_QUERY_DEVICE_IDS,
542
0
            msg);
543
0
  }
544
545
0
  struct nsm_query_device_ids_resp *response =
546
0
      (struct nsm_query_device_ids_resp *)msg->payload;
547
0
  response->hdr.command = NSM_QUERY_DEVICE_IDS;
548
0
  response->hdr.completion_code = cc;
549
0
  response->hdr.data_size = htole16(NSM_DEBUG_TOKEN_DEVICE_ID_SIZE);
550
0
  memcpy(response->device_id, device_id, NSM_DEBUG_TOKEN_DEVICE_ID_SIZE);
551
552
0
  return NSM_SW_SUCCESS;
553
0
}