Coverage Report

Created: 2025-10-13 07:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/p11-kit/p11-kit/rpc-message.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2008 Stefan Walter
3
 * Copyright (C) 2012 Red Hat Inc.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 *
9
 *     * Redistributions of source code must retain the above
10
 *       copyright notice, this list of conditions and the
11
 *       following disclaimer.
12
 *     * Redistributions in binary form must reproduce the
13
 *       above copyright notice, this list of conditions and
14
 *       the following disclaimer in the documentation and/or
15
 *       other materials provided with the distribution.
16
 *     * The names of contributors to this software may not be
17
 *       used to endorse or promote products derived from this
18
 *       software without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30
 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31
 * DAMAGE.
32
 *
33
 * Author: Stef Walter <stefw@gnome.org>
34
 */
35
36
#include "config.h"
37
38
249
#define P11_DEBUG_FLAG P11_DEBUG_RPC
39
#include "attrs.h"
40
#include "debug.h"
41
#include "library.h"
42
#include "message.h"
43
#include "private.h"
44
#include "rpc-message.h"
45
46
#include <assert.h>
47
#include <errno.h>
48
#include <string.h>
49
50
#ifdef ENABLE_NLS
51
#include <libintl.h>
52
6
#define _(x) dgettext(PACKAGE_NAME, x)
53
#else
54
#define _(x) (x)
55
#endif
56
57
278
#define ELEMS(x) (sizeof (x) / sizeof (x[0]))
58
59
void
60
p11_rpc_message_init (p11_rpc_message *msg,
61
                      p11_buffer *input,
62
                      p11_buffer *output)
63
46
{
64
46
  assert (input != NULL);
65
46
  assert (output != NULL);
66
46
  assert (output->ffree != NULL);
67
46
  assert (output->frealloc != NULL);
68
69
46
  memset (msg, 0, sizeof (*msg));
70
71
46
  msg->output = output;
72
46
  msg->input = input;
73
46
}
74
75
void
76
p11_rpc_message_clear (p11_rpc_message *msg)
77
46
{
78
46
  void *allocated;
79
46
  void **data;
80
81
46
  assert (msg != NULL);
82
83
  /* Free up the extra allocated memory */
84
46
  allocated = msg->extra;
85
189
  while (allocated != NULL) {
86
143
    data = (void **)allocated;
87
88
    /* Pointer to the next allocation */
89
143
    allocated = *data;
90
143
    assert (msg->output->ffree);
91
143
    (msg->output->ffree) (data);
92
143
  }
93
94
46
  msg->output = NULL;
95
46
  msg->input = NULL;
96
46
  msg->extra = NULL;
97
46
}
98
99
void *
100
p11_rpc_message_alloc_extra (p11_rpc_message *msg,
101
                             size_t length)
102
144
{
103
144
  void **data;
104
105
144
  assert (msg != NULL);
106
107
144
  if (length > 0x7fffffff)
108
1
    return NULL;
109
110
144
  assert (msg->output->frealloc != NULL);
111
143
  data = (msg->output->frealloc) (NULL, sizeof (void *) + length);
112
143
  if (data == NULL)
113
0
    return NULL;
114
115
  /* Munch up the memory to help catch bugs */
116
143
  memset (data, 0xff, sizeof (void *) + length);
117
118
  /* Store pointer to next allocated block at beginning */
119
143
  *data = msg->extra;
120
143
  msg->extra = data;
121
122
  /* Data starts after first pointer */
123
143
  return (void *)(data + 1);
124
143
}
125
126
void *
127
p11_rpc_message_alloc_extra_array (p11_rpc_message *msg,
128
           size_t nmemb,
129
           size_t size)
130
21
{
131
21
  if (nmemb != 0 && (SIZE_MAX - sizeof (void *)) / nmemb < size) {
132
0
    errno = ENOMEM;
133
0
    return NULL;
134
0
  }
135
21
  return p11_rpc_message_alloc_extra (msg, nmemb * size);
136
21
}
137
138
bool
139
p11_rpc_message_prep (p11_rpc_message *msg,
140
                      int call_id,
141
                      p11_rpc_message_type type)
142
48
{
143
48
  int len;
144
145
48
  assert (type != 0);
146
48
  assert (call_id >= P11_RPC_CALL_ERROR);
147
48
  assert (call_id < P11_RPC_CALL_MAX);
148
149
48
  p11_buffer_reset (msg->output, 0);
150
48
  msg->signature = NULL;
151
152
  /* The call id and signature */
153
48
  if (type == P11_RPC_REQUEST)
154
0
    msg->signature = p11_rpc_calls[call_id].request;
155
48
  else if (type == P11_RPC_RESPONSE)
156
48
    msg->signature = p11_rpc_calls[call_id].response;
157
0
  else
158
0
    assert_not_reached ();
159
48
  assert (msg->signature != NULL);
160
48
  msg->sigverify = msg->signature;
161
162
48
  msg->call_id = call_id;
163
48
  msg->call_type = type;
164
165
  /* Encode the two of them */
166
48
  p11_rpc_buffer_add_uint32 (msg->output, call_id);
167
48
  if (msg->signature) {
168
48
    len = strlen (msg->signature);
169
48
    p11_rpc_buffer_add_byte_array (msg->output, (unsigned char*)msg->signature, len);
170
48
  }
171
172
48
  msg->parsed = 0;
173
48
  return !p11_buffer_failed (msg->output);
174
48
}
175
176
bool
177
p11_rpc_message_parse (p11_rpc_message *msg,
178
                       p11_rpc_message_type type)
179
46
{
180
46
  const unsigned char *val;
181
46
  size_t len;
182
46
  uint32_t call_id;
183
184
46
  assert (msg != NULL);
185
46
  assert (msg->input != NULL);
186
187
46
  msg->parsed = 0;
188
189
  /* Pull out the call identifier */
190
46
  if (!p11_rpc_buffer_get_uint32 (msg->input, &msg->parsed, &call_id)) {
191
0
    p11_message (_("invalid message: couldn't read call identifier"));
192
0
    return false;
193
0
  }
194
195
46
  msg->signature = msg->sigverify = NULL;
196
197
  /* The call id and signature */
198
46
  if (call_id >= P11_RPC_CALL_MAX ||
199
43
      (type == P11_RPC_REQUEST && call_id == P11_RPC_CALL_ERROR)) {
200
6
    p11_message (_("invalid message: bad call id: %d"), call_id);
201
6
    return false;
202
6
  }
203
40
  if (type == P11_RPC_REQUEST)
204
40
    msg->signature = p11_rpc_calls[call_id].request;
205
0
  else if (type == P11_RPC_RESPONSE)
206
0
    msg->signature = p11_rpc_calls[call_id].response;
207
0
  else
208
0
    assert_not_reached ();
209
40
  assert (msg->signature != NULL);
210
40
  msg->call_id = call_id;
211
40
  msg->call_type = type;
212
40
  msg->sigverify = msg->signature;
213
214
  /* Verify the incoming signature */
215
40
  if (!p11_rpc_buffer_get_byte_array (msg->input, &msg->parsed, &val, &len) ||
216
      /* This can happen if the length header == 0xffffffff */
217
40
      val == NULL) {
218
0
    p11_message (_("invalid message: couldn't read signature"));
219
0
    return false;
220
0
  }
221
222
40
  if ((strlen (msg->signature) != len) || (memcmp (val, msg->signature, len) != 0)) {
223
0
    p11_message (_("invalid message: signature doesn't match"));
224
0
    return false;
225
0
  }
226
227
40
  return true;
228
40
}
229
230
bool
231
p11_rpc_message_verify_part (p11_rpc_message *msg,
232
                             const char* part)
233
115
{
234
115
  int len;
235
115
  bool ok;
236
237
115
  if (!msg->sigverify)
238
0
    return true;
239
240
115
  len = strlen (part);
241
115
  ok = (strncmp (msg->sigverify, part, len) == 0);
242
115
  if (ok)
243
115
    msg->sigverify += len;
244
115
  return ok;
245
115
}
246
247
static void
248
p11_rpc_message_write_attribute_buffer_array (p11_rpc_message *msg,
249
                CK_ATTRIBUTE_PTR arr,
250
                CK_ULONG num)
251
0
{
252
0
  CK_ATTRIBUTE_PTR attr;
253
0
  CK_ULONG i;
254
255
0
  assert (num == 0 || arr != NULL);
256
257
  /* Write the number of items */
258
0
  p11_rpc_buffer_add_uint32 (msg->output, num);
259
260
0
  for (i = 0; i < num; ++i) {
261
0
    attr = arr + i;
262
263
    /* The attribute type */
264
0
    p11_rpc_buffer_add_uint32 (msg->output, attr->type);
265
266
    /* And the attribute buffer length */
267
0
    p11_rpc_buffer_add_uint32 (msg->output, attr->pValue ? attr->ulValueLen : 0);
268
269
0
    if (attr->pValue && IS_ATTRIBUTE_ARRAY (attr))
270
0
      p11_rpc_message_write_attribute_buffer_array (
271
0
        msg, attr->pValue,
272
0
        attr->ulValueLen / sizeof (CK_ATTRIBUTE));
273
0
  }
274
0
}
275
276
bool
277
p11_rpc_message_write_attribute_buffer (p11_rpc_message *msg,
278
          CK_ATTRIBUTE_PTR arr,
279
          CK_ULONG num)
280
0
{
281
0
  assert (msg != NULL);
282
0
  assert (msg->output != NULL);
283
284
  /* Make sure this is in the right order */
285
0
  assert (!msg->signature || p11_rpc_message_verify_part (msg, "fA"));
286
287
0
  p11_rpc_message_write_attribute_buffer_array (msg, arr, num);
288
0
  return !p11_buffer_failed (msg->output);
289
0
}
290
291
bool
292
p11_rpc_message_write_attribute_array (p11_rpc_message *msg,
293
                                       CK_ATTRIBUTE_PTR arr,
294
                                       CK_ULONG num)
295
0
{
296
0
  CK_ULONG i;
297
298
0
  assert (num == 0 || arr != NULL);
299
0
  assert (msg != NULL);
300
0
  assert (msg->output != NULL);
301
302
  /* Make sure this is in the right order */
303
0
  assert (!msg->signature || p11_rpc_message_verify_part (msg, "aA"));
304
305
  /* Write the number of items */
306
0
  p11_rpc_buffer_add_uint32 (msg->output, num);
307
308
0
  for (i = 0; i < num; ++i)
309
0
    p11_rpc_buffer_add_attribute (msg->output, &(arr[i]));
310
311
0
  return !p11_buffer_failed (msg->output);
312
0
}
313
314
bool
315
p11_rpc_message_read_byte (p11_rpc_message *msg,
316
                           CK_BYTE *val)
317
0
{
318
0
  assert (msg != NULL);
319
0
  assert (msg->input != NULL);
320
321
  /* Make sure this is in the right order */
322
0
  assert (!msg->signature || p11_rpc_message_verify_part (msg, "y"));
323
0
  return p11_rpc_buffer_get_byte (msg->input, &msg->parsed, val);
324
0
}
325
326
bool
327
p11_rpc_message_write_byte (p11_rpc_message *msg,
328
                            CK_BYTE val)
329
0
{
330
0
  assert (msg != NULL);
331
0
  assert (msg->output != NULL);
332
333
  /* Make sure this is in the right order */
334
0
  assert (!msg->signature || p11_rpc_message_verify_part (msg, "y"));
335
0
  p11_rpc_buffer_add_byte (msg->output, val);
336
0
  return !p11_buffer_failed (msg->output);
337
0
}
338
339
bool
340
p11_rpc_message_read_ulong (p11_rpc_message *msg,
341
                            CK_ULONG *val)
342
44
{
343
44
  uint64_t v;
344
345
44
  assert (msg != NULL);
346
44
  assert (msg->input != NULL);
347
348
  /* Make sure this is in the right order */
349
44
  assert (!msg->signature || p11_rpc_message_verify_part (msg, "u"));
350
351
44
  if (!p11_rpc_buffer_get_uint64 (msg->input, &msg->parsed, &v))
352
0
    return false;
353
44
  if (val)
354
44
    *val = (CK_ULONG)v;
355
44
  return true;
356
44
}
357
358
bool
359
p11_rpc_message_write_ulong (p11_rpc_message *msg,
360
                             CK_ULONG val)
361
31
{
362
31
  assert (msg != NULL);
363
31
  assert (msg->output != NULL);
364
365
  /* Make sure this is in the right order */
366
31
  assert (!msg->signature || p11_rpc_message_verify_part (msg, "u"));
367
31
  p11_rpc_buffer_add_uint64 (msg->output, val);
368
31
  return !p11_buffer_failed (msg->output);
369
31
}
370
371
bool
372
p11_rpc_message_write_byte_buffer (p11_rpc_message *msg,
373
                                   CK_ULONG count)
374
0
{
375
0
  assert (msg != NULL);
376
0
  assert (msg->output != NULL);
377
378
  /* Make sure this is in the right order */
379
0
  assert (!msg->signature || p11_rpc_message_verify_part (msg, "fy"));
380
0
  p11_rpc_buffer_add_uint32 (msg->output, count);
381
0
  return !p11_buffer_failed (msg->output);
382
0
}
383
384
bool
385
p11_rpc_message_write_byte_array (p11_rpc_message *msg,
386
                                  CK_BYTE_PTR arr,
387
                                  CK_ULONG num)
388
0
{
389
0
  assert (msg != NULL);
390
0
  assert (msg->output != NULL);
391
392
  /* Make sure this is in the right order */
393
0
  assert (!msg->signature || p11_rpc_message_verify_part (msg, "ay"));
394
395
  /* No array, no data, just length */
396
0
  if (!arr && num != 0) {
397
0
    p11_rpc_buffer_add_byte (msg->output, 0);
398
0
    p11_rpc_buffer_add_uint32 (msg->output, num);
399
0
  } else {
400
0
    p11_rpc_buffer_add_byte (msg->output, 1);
401
0
    p11_rpc_buffer_add_byte_array (msg->output, arr, num);
402
0
  }
403
404
0
  return !p11_buffer_failed (msg->output);
405
0
}
406
407
bool
408
p11_rpc_message_write_ulong_buffer (p11_rpc_message *msg,
409
                                    CK_ULONG count)
410
0
{
411
0
  assert (msg != NULL);
412
0
  assert (msg->output != NULL);
413
414
  /* Make sure this is in the right order */
415
0
  assert (!msg->signature || p11_rpc_message_verify_part (msg, "fu"));
416
0
  p11_rpc_buffer_add_uint32 (msg->output, count);
417
0
  return !p11_buffer_failed (msg->output);
418
0
}
419
420
bool
421
p11_rpc_message_write_ulong_array (p11_rpc_message *msg,
422
                                   CK_ULONG_PTR array,
423
                                   CK_ULONG n_array)
424
0
{
425
0
  CK_ULONG i;
426
427
0
  assert (msg != NULL);
428
0
  assert (msg->output != NULL);
429
430
  /* Check that we're supposed to have this at this point */
431
0
  assert (!msg->signature || p11_rpc_message_verify_part (msg, "au"));
432
433
  /* We send a byte which determines whether there's actual data present or not */
434
0
  p11_rpc_buffer_add_byte (msg->output, array ? 1 : 0);
435
0
  p11_rpc_buffer_add_uint32 (msg->output, n_array);
436
437
  /* Now send the data if valid */
438
0
  if (array) {
439
0
    for (i = 0; i < n_array; ++i)
440
0
      p11_rpc_buffer_add_uint64 (msg->output, array[i]);
441
0
  }
442
443
0
  return !p11_buffer_failed (msg->output);
444
0
}
445
446
bool
447
p11_rpc_message_read_version (p11_rpc_message *msg,
448
                              CK_VERSION *version)
449
0
{
450
0
  assert (msg != NULL);
451
0
  assert (msg->input != NULL);
452
0
  assert (version != NULL);
453
454
  /* Check that we're supposed to have this at this point */
455
0
  assert (!msg->signature || p11_rpc_message_verify_part (msg, "v"));
456
457
0
  return p11_rpc_buffer_get_byte (msg->input, &msg->parsed, &version->major) &&
458
0
         p11_rpc_buffer_get_byte (msg->input, &msg->parsed, &version->minor);
459
0
}
460
461
bool
462
p11_rpc_message_write_version (p11_rpc_message *msg,
463
                               CK_VERSION *version)
464
0
{
465
0
  assert (msg != NULL);
466
0
  assert (msg->output != NULL);
467
0
  assert (version != NULL);
468
469
  /* Check that we're supposed to have this at this point */
470
0
  assert (!msg->signature || p11_rpc_message_verify_part (msg, "v"));
471
472
0
  p11_rpc_buffer_add_byte (msg->output, version->major);
473
0
  p11_rpc_buffer_add_byte (msg->output, version->minor);
474
475
0
  return !p11_buffer_failed (msg->output);
476
0
}
477
478
bool
479
p11_rpc_message_read_space_string (p11_rpc_message *msg,
480
                                   CK_UTF8CHAR *buffer,
481
                                   CK_ULONG length)
482
0
{
483
0
  const unsigned char *data;
484
0
  size_t n_data;
485
486
0
  assert (msg != NULL);
487
0
  assert (msg->input != NULL);
488
0
  assert (buffer != NULL);
489
0
  assert (length != 0);
490
491
0
  assert (!msg->signature || p11_rpc_message_verify_part (msg, "s"));
492
493
0
  if (!p11_rpc_buffer_get_byte_array (msg->input, &msg->parsed, &data, &n_data))
494
0
    return false;
495
496
0
  if (n_data != length) {
497
0
    p11_message (_("invalid length space padded string received: %d != %d"),
498
0
                 (int)length, (int)n_data);
499
0
    return false;
500
0
  }
501
502
0
  memcpy (buffer, data, length);
503
0
  return true;
504
0
}
505
506
bool
507
p11_rpc_message_write_space_string (p11_rpc_message *msg,
508
                                    CK_UTF8CHAR *data,
509
                                    CK_ULONG length)
510
0
{
511
0
  assert (msg != NULL);
512
0
  assert (msg->output != NULL);
513
0
  assert (data != NULL);
514
0
  assert (length != 0);
515
516
0
  assert (!msg->signature || p11_rpc_message_verify_part (msg, "s"));
517
518
0
  p11_rpc_buffer_add_byte_array (msg->output, data, length);
519
0
  return !p11_buffer_failed (msg->output);
520
0
}
521
522
bool
523
p11_rpc_message_write_zero_string (p11_rpc_message *msg,
524
                                   CK_UTF8CHAR *string)
525
0
{
526
0
  assert (msg != NULL);
527
0
  assert (msg->output != NULL);
528
0
  assert (string != NULL);
529
530
0
  assert (!msg->signature || p11_rpc_message_verify_part (msg, "z"));
531
532
0
  p11_rpc_buffer_add_byte_array (msg->output, string,
533
0
                                 string ? strlen ((char *)string) : 0);
534
0
  return !p11_buffer_failed (msg->output);
535
0
}
536
537
static void *
538
log_allocator (void *pointer,
539
               size_t size)
540
0
{
541
0
  void *result = realloc (pointer, (size_t)size);
542
0
  return_val_if_fail (!size || result != NULL, NULL);
543
0
  return result;
544
0
}
545
546
p11_buffer *
547
p11_rpc_buffer_new (size_t reserve)
548
0
{
549
0
  return p11_rpc_buffer_new_full (reserve, log_allocator, free);
550
0
}
551
552
p11_buffer *
553
p11_rpc_buffer_new_full (size_t reserve,
554
                         void * (* frealloc) (void *data, size_t size),
555
                         void (* ffree) (void *data))
556
0
{
557
0
  p11_buffer *buffer;
558
559
0
  buffer = calloc (1, sizeof (p11_buffer));
560
0
  return_val_if_fail (buffer != NULL, NULL);
561
562
0
  p11_buffer_init_full (buffer, NULL, 0, 0, frealloc, ffree);
563
0
  if (!p11_buffer_reset (buffer, reserve))
564
0
    return_val_if_reached (NULL);
565
566
0
  return buffer;
567
0
}
568
569
void
570
p11_rpc_buffer_free (p11_buffer *buf)
571
0
{
572
0
  if (buf == NULL)
573
0
    return;
574
575
0
  p11_buffer_uninit (buf);
576
0
  free (buf);
577
0
}
578
579
void
580
p11_rpc_buffer_add_byte (p11_buffer *buf,
581
                         unsigned char value)
582
0
{
583
0
  p11_buffer_add (buf, &value, 1);
584
0
}
585
586
int
587
p11_rpc_buffer_get_byte (p11_buffer *buf,
588
                         size_t *offset,
589
                         unsigned char *val)
590
1.23k
{
591
1.23k
  unsigned char *ptr;
592
1.23k
  if (buf->len < 1 || *offset > buf->len - 1) {
593
0
    p11_buffer_fail (buf);
594
0
    return 0;
595
0
  }
596
1.23k
  ptr = (unsigned char *)buf->data + *offset;
597
1.23k
  if (val != NULL)
598
1.23k
    *val = *ptr;
599
1.23k
  *offset = *offset + 1;
600
1.23k
  return 1;
601
1.23k
}
602
603
void
604
p11_rpc_buffer_encode_uint16 (unsigned char* data,
605
                              uint16_t value)
606
0
{
607
0
  data[0] = (value >> 8) & 0xff;
608
0
  data[1] = (value >> 0) & 0xff;
609
0
}
610
611
uint16_t
612
p11_rpc_buffer_decode_uint16 (unsigned char* data)
613
0
{
614
0
  uint16_t value = data[0] << 8 | data[1];
615
0
  return value;
616
0
}
617
618
void
619
p11_rpc_buffer_add_uint16 (p11_buffer *buffer,
620
                           uint16_t value)
621
0
{
622
0
  size_t offset = buffer->len;
623
0
  if (!p11_buffer_append (buffer, 2))
624
0
    return_if_reached ();
625
0
  p11_rpc_buffer_set_uint16 (buffer, offset, value);
626
0
}
627
628
bool
629
p11_rpc_buffer_set_uint16 (p11_buffer *buffer,
630
                           size_t offset,
631
                           uint16_t value)
632
0
{
633
0
  unsigned char *ptr;
634
0
  if (buffer->len < 2 || offset > buffer->len - 2) {
635
0
    p11_buffer_fail (buffer);
636
0
    return false;
637
0
  }
638
0
  ptr = (unsigned char *)buffer->data + offset;
639
0
  p11_rpc_buffer_encode_uint16 (ptr, value);
640
0
  return true;
641
0
}
642
643
bool
644
p11_rpc_buffer_get_uint16 (p11_buffer *buf,
645
                           size_t *offset,
646
                           uint16_t *value)
647
0
{
648
0
  unsigned char *ptr;
649
0
  if (buf->len < 2 || *offset > buf->len - 2) {
650
0
    p11_buffer_fail (buf);
651
0
    return false;
652
0
  }
653
0
  ptr = (unsigned char*)buf->data + *offset;
654
0
  if (value != NULL)
655
0
    *value = p11_rpc_buffer_decode_uint16 (ptr);
656
0
  *offset = *offset + 2;
657
0
  return true;
658
0
}
659
660
void
661
p11_rpc_buffer_encode_uint32 (unsigned char* data,
662
                          uint32_t value)
663
158
{
664
158
  data[0] = (value >> 24) & 0xff;
665
158
  data[1] = (value >> 16) & 0xff;
666
158
  data[2] = (value >> 8) & 0xff;
667
158
  data[3] = (value >> 0) & 0xff;
668
158
}
669
670
uint32_t
671
p11_rpc_buffer_decode_uint32 (unsigned char* ptr)
672
3.44k
{
673
3.44k
  uint32_t val = (uint32_t) ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
674
3.44k
  return val;
675
3.44k
}
676
677
void
678
p11_rpc_buffer_add_uint32 (p11_buffer *buffer,
679
                           uint32_t value)
680
158
{
681
158
  size_t offset = buffer->len;
682
158
  if (!p11_buffer_append (buffer, 4))
683
0
    return_val_if_reached ();
684
158
  p11_rpc_buffer_set_uint32 (buffer, offset, value);
685
158
}
686
687
bool
688
p11_rpc_buffer_set_uint32 (p11_buffer *buffer,
689
                           size_t offset,
690
                           uint32_t value)
691
158
{
692
158
  unsigned char *ptr;
693
158
  if (buffer->len < 4 || offset > buffer->len - 4) {
694
0
    p11_buffer_fail (buffer);
695
0
    return false;
696
0
  }
697
158
  ptr = (unsigned char*)buffer->data + offset;
698
158
  p11_rpc_buffer_encode_uint32 (ptr, value);
699
158
  return true;
700
158
}
701
702
bool
703
p11_rpc_buffer_get_uint32 (p11_buffer *buf,
704
                           size_t *offset,
705
                           uint32_t *value)
706
3.44k
{
707
3.44k
  unsigned char *ptr;
708
3.44k
  if (buf->len < 4 || *offset > buf->len - 4) {
709
0
    p11_buffer_fail (buf);
710
0
    return false;
711
0
  }
712
3.44k
  ptr = (unsigned char*)buf->data + *offset;
713
3.44k
  if (value != NULL)
714
3.44k
    *value = p11_rpc_buffer_decode_uint32 (ptr);
715
3.44k
  *offset = *offset + 4;
716
3.44k
  return true;
717
3.44k
}
718
719
void
720
p11_rpc_buffer_add_uint64 (p11_buffer *buffer,
721
                           uint64_t value)
722
31
{
723
31
  p11_rpc_buffer_add_uint32 (buffer, ((value >> 32) & 0xffffffff));
724
31
  p11_rpc_buffer_add_uint32 (buffer, (value & 0xffffffff));
725
31
}
726
727
bool
728
p11_rpc_buffer_get_uint64 (p11_buffer *buf,
729
                           size_t *offset,
730
                           uint64_t *value)
731
566
{
732
566
  size_t off = *offset;
733
566
  uint32_t a, b;
734
566
  if (!p11_rpc_buffer_get_uint32 (buf, &off, &a) ||
735
566
      !p11_rpc_buffer_get_uint32 (buf, &off, &b))
736
0
    return false;
737
566
  if (value != NULL)
738
566
    *value = ((uint64_t)a) << 32 | b;
739
566
  *offset = off;
740
566
  return true;
741
566
}
742
743
void
744
p11_rpc_buffer_add_byte_array (p11_buffer *buffer,
745
                               const unsigned char *data,
746
                               size_t length)
747
48
{
748
48
  if (data == NULL) {
749
0
    p11_rpc_buffer_add_uint32 (buffer, 0xffffffff);
750
0
    return;
751
48
  } else if (length >= 0x7fffffff) {
752
0
    p11_buffer_fail (buffer);
753
0
    return;
754
0
  }
755
48
  p11_rpc_buffer_add_uint32 (buffer, length);
756
48
  p11_buffer_add (buffer, data, length);
757
48
}
758
759
bool
760
p11_rpc_buffer_get_byte_array (p11_buffer *buf,
761
                               size_t *offset,
762
                               const unsigned char **data,
763
                               size_t *length)
764
506
{
765
506
  size_t off = *offset;
766
506
  uint32_t len;
767
506
  if (!p11_rpc_buffer_get_uint32 (buf, &off, &len))
768
0
    return false;
769
506
  if (len == 0xffffffff) {
770
0
    *offset = off;
771
0
    if (data)
772
0
      *data = NULL;
773
0
    if (length)
774
0
      *length = 0;
775
0
    return true;
776
506
  } else if (len >= 0x7fffffff) {
777
4
    p11_buffer_fail (buf);
778
4
    return false;
779
4
  }
780
781
502
  if (buf->len < len || off > buf->len - len) {
782
5
    p11_buffer_fail (buf);
783
5
    return false;
784
5
  }
785
786
497
  if (data)
787
497
    *data = (unsigned char *)buf->data + off;
788
497
  if (length)
789
497
    *length = len;
790
497
  *offset = off + len;
791
792
497
  return true;
793
502
}
794
795
static p11_rpc_value_type
796
map_attribute_to_value_type (CK_ATTRIBUTE_TYPE type)
797
458
{
798
458
  switch (type) {
799
0
  case CKA_TOKEN:
800
0
  case CKA_PRIVATE:
801
0
  case CKA_TRUSTED:
802
0
  case CKA_SENSITIVE:
803
0
  case CKA_ENCRYPT:
804
0
  case CKA_DECRYPT:
805
0
  case CKA_WRAP:
806
0
  case CKA_UNWRAP:
807
0
  case CKA_SIGN:
808
0
  case CKA_SIGN_RECOVER:
809
0
  case CKA_VERIFY:
810
0
  case CKA_VERIFY_RECOVER:
811
0
  case CKA_DERIVE:
812
0
  case CKA_EXTRACTABLE:
813
0
  case CKA_LOCAL:
814
0
  case CKA_NEVER_EXTRACTABLE:
815
0
  case CKA_ALWAYS_SENSITIVE:
816
0
  case CKA_MODIFIABLE:
817
0
  case CKA_COPYABLE:
818
3
  case CKA_SECONDARY_AUTH: /* Deprecated */
819
3
  case CKA_ALWAYS_AUTHENTICATE:
820
3
  case CKA_WRAP_WITH_TRUSTED:
821
3
  case CKA_RESET_ON_INIT:
822
3
  case CKA_HAS_RESET:
823
3
  case CKA_COLOR:
824
3
  case CKA_IBM_RESTRICTABLE:
825
3
  case CKA_IBM_NEVER_MODIFIABLE:
826
3
  case CKA_IBM_RETAINKEY:
827
3
  case CKA_IBM_ATTRBOUND:
828
3
  case CKA_IBM_USE_AS_DATA:
829
3
  case CKA_IBM_PROTKEY_EXTRACTABLE:
830
3
  case CKA_IBM_PROTKEY_NEVER_EXTRACTABLE:
831
3
    return P11_RPC_VALUE_BYTE;
832
37
  case CKA_CLASS:
833
37
  case CKA_CERTIFICATE_TYPE:
834
37
  case CKA_CERTIFICATE_CATEGORY:
835
37
  case CKA_JAVA_MIDP_SECURITY_DOMAIN:
836
37
  case CKA_KEY_TYPE:
837
37
  case CKA_MODULUS_BITS:
838
37
  case CKA_PRIME_BITS:
839
37
  case CKA_SUB_PRIME_BITS:
840
37
  case CKA_VALUE_BITS:
841
37
  case CKA_VALUE_LEN:
842
37
  case CKA_KEY_GEN_MECHANISM:
843
37
  case CKA_AUTH_PIN_FLAGS: /* Deprecated */
844
37
  case CKA_HW_FEATURE_TYPE:
845
37
  case CKA_PIXEL_X:
846
37
  case CKA_PIXEL_Y:
847
37
  case CKA_RESOLUTION:
848
37
  case CKA_CHAR_ROWS:
849
37
  case CKA_CHAR_COLUMNS:
850
37
  case CKA_BITS_PER_PIXEL:
851
37
  case CKA_MECHANISM_TYPE:
852
37
  case CKA_IBM_DILITHIUM_KEYFORM:
853
37
  case CKA_IBM_CCA_AES_KEY_MODE:
854
37
  case CKA_IBM_STD_COMPLIANCE1:
855
37
  case CKA_IBM_KEYTYPE:
856
37
  case CKA_IBM_KYBER_KEYFORM:
857
37
    return P11_RPC_VALUE_ULONG;
858
4
  case CKA_WRAP_TEMPLATE:
859
4
  case CKA_UNWRAP_TEMPLATE:
860
4
  case CKA_DERIVE_TEMPLATE:
861
4
    return P11_RPC_VALUE_ATTRIBUTE_ARRAY;
862
20
  case CKA_ALLOWED_MECHANISMS:
863
20
    return P11_RPC_VALUE_MECHANISM_TYPE_ARRAY;
864
0
  case CKA_START_DATE:
865
0
  case CKA_END_DATE:
866
0
    return P11_RPC_VALUE_DATE;
867
249
  default:
868
249
    p11_debug ("cannot determine the type of attribute value for %lu; assuming byte array",
869
249
         type);
870
    /* fallthrough */
871
249
  case CKA_LABEL:
872
249
  case CKA_APPLICATION:
873
249
  case CKA_VALUE:
874
249
  case CKA_OBJECT_ID:
875
296
  case CKA_ISSUER:
876
296
  case CKA_SERIAL_NUMBER:
877
296
  case CKA_AC_ISSUER:
878
296
  case CKA_OWNER:
879
296
  case CKA_ATTR_TYPES:
880
296
  case CKA_URL:
881
296
  case CKA_HASH_OF_SUBJECT_PUBLIC_KEY:
882
296
  case CKA_HASH_OF_ISSUER_PUBLIC_KEY:
883
296
  case CKA_CHECK_VALUE:
884
296
  case CKA_SUBJECT:
885
296
  case CKA_ID:
886
296
  case CKA_MODULUS:
887
296
  case CKA_PUBLIC_EXPONENT:
888
296
  case CKA_PRIVATE_EXPONENT:
889
296
  case CKA_PRIME_1:
890
296
  case CKA_PRIME_2:
891
296
  case CKA_EXPONENT_1:
892
296
  case CKA_EXPONENT_2:
893
312
  case CKA_COEFFICIENT:
894
312
  case CKA_PRIME:
895
312
  case CKA_SUBPRIME:
896
312
  case CKA_BASE:
897
312
  case CKA_EC_PARAMS:
898
    /* same as CKA_ECDSA_PARAMS */
899
312
  case CKA_EC_POINT:
900
312
  case CKA_CHAR_SETS:
901
337
  case CKA_ENCODING_METHODS:
902
385
  case CKA_MIME_TYPES:
903
385
  case CKA_REQUIRED_CMS_ATTRIBUTES:
904
385
  case CKA_DEFAULT_CMS_ATTRIBUTES:
905
385
  case CKA_SUPPORTED_CMS_ATTRIBUTES:
906
394
  case CKA_IBM_OPAQUE:
907
394
  case CKA_IBM_OPAQUE_REENC:
908
394
  case CKA_IBM_OPAQUE_OLD:
909
394
  case CKA_IBM_CV:
910
394
  case CKA_IBM_MACKEY:
911
394
  case CKA_IBM_STRUCT_PARAMS:
912
394
  case CKA_IBM_OPAQUE_PKEY:
913
394
  case CKA_IBM_DILITHIUM_MODE:
914
394
  case CKA_IBM_DILITHIUM_RHO:
915
394
  case CKA_IBM_DILITHIUM_SEED:
916
394
  case CKA_IBM_DILITHIUM_TR:
917
394
  case CKA_IBM_DILITHIUM_S1:
918
394
  case CKA_IBM_DILITHIUM_S2:
919
394
  case CKA_IBM_DILITHIUM_T0:
920
394
  case CKA_IBM_DILITHIUM_T1:
921
394
  case CKA_IBM_KYBER_MODE:
922
394
  case CKA_IBM_KYBER_PK:
923
394
  case CKA_IBM_KYBER_SK:
924
394
    return P11_RPC_VALUE_BYTE_ARRAY;
925
458
  }
926
458
}
927
928
static bool
929
p11_rpc_message_get_byte_value (p11_rpc_message *msg,
930
              p11_buffer *buffer,
931
              size_t *offset,
932
              void *value,
933
              CK_ULONG *value_length)
934
6
{
935
6
  return p11_rpc_buffer_get_byte_value (buffer, offset, value, value_length);
936
6
}
937
938
static bool
939
p11_rpc_message_get_ulong_value (p11_rpc_message *msg,
940
               p11_buffer *buffer,
941
               size_t *offset,
942
               void *value,
943
               CK_ULONG *value_length)
944
62
{
945
62
  return p11_rpc_buffer_get_ulong_value (buffer, offset, value, value_length);
946
62
}
947
948
static bool
949
p11_rpc_message_get_attribute_array_value (p11_rpc_message *msg,
950
             p11_buffer *buffer,
951
             size_t *offset,
952
             void *value,
953
             CK_ULONG *value_length)
954
8
{
955
8
  uint32_t count, i;
956
8
  CK_ATTRIBUTE *attr = value;
957
958
8
  if (!p11_rpc_buffer_get_uint32 (buffer, offset, &count))
959
0
    return false;
960
961
8
  if (value_length != NULL)
962
4
    *value_length = count * sizeof (CK_ATTRIBUTE);
963
964
8
  if (value == NULL)
965
4
    return true;
966
967
16
  for (i = 0; i < count; ++i)
968
16
    if (!p11_rpc_message_get_attribute (msg, buffer, offset, attr + i))
969
4
      return false;
970
971
0
  return true;
972
4
}
973
974
static bool
975
p11_rpc_message_get_mechanism_type_array_value (p11_rpc_message *msg,
976
                  p11_buffer *buffer,
977
                  size_t *offset,
978
                  void *value,
979
                  CK_ULONG *value_length)
980
40
{
981
40
  return p11_rpc_buffer_get_mechanism_type_array_value (buffer, offset, value, value_length);
982
40
}
983
984
static bool
985
p11_rpc_message_get_date_value (p11_rpc_message *msg,
986
              p11_buffer *buffer,
987
              size_t *offset,
988
              void *value,
989
              CK_ULONG *value_length)
990
0
{
991
0
  return p11_rpc_buffer_get_date_value (buffer, offset, value, value_length);
992
0
}
993
994
static bool
995
p11_rpc_message_get_byte_array_value (p11_rpc_message *msg,
996
              p11_buffer *buffer,
997
              size_t *offset,
998
              void *value,
999
              CK_ULONG *value_length)
1000
430
{
1001
430
  return p11_rpc_buffer_get_byte_array_value (buffer, offset, value, value_length);
1002
430
}
1003
1004
typedef struct {
1005
  p11_rpc_value_type type;
1006
  p11_rpc_value_encoder encode;
1007
  p11_rpc_message_decoder decode;
1008
} p11_rpc_attribute_serializer;
1009
1010
static p11_rpc_attribute_serializer p11_rpc_attribute_serializers[] = {
1011
  { P11_RPC_VALUE_BYTE, p11_rpc_buffer_add_byte_value, p11_rpc_message_get_byte_value },
1012
  { P11_RPC_VALUE_ULONG, p11_rpc_buffer_add_ulong_value, p11_rpc_message_get_ulong_value },
1013
  { P11_RPC_VALUE_ATTRIBUTE_ARRAY, p11_rpc_buffer_add_attribute_array_value, p11_rpc_message_get_attribute_array_value },
1014
  { P11_RPC_VALUE_MECHANISM_TYPE_ARRAY, p11_rpc_buffer_add_mechanism_type_array_value, p11_rpc_message_get_mechanism_type_array_value },
1015
  { P11_RPC_VALUE_DATE, p11_rpc_buffer_add_date_value, p11_rpc_message_get_date_value },
1016
  { P11_RPC_VALUE_BYTE_ARRAY, p11_rpc_buffer_add_byte_array_value, p11_rpc_message_get_byte_array_value }
1017
};
1018
1019
P11_STATIC_ASSERT(sizeof(CK_BYTE) <= sizeof(uint8_t));
1020
1021
void
1022
p11_rpc_buffer_add_byte_value (p11_buffer *buffer,
1023
             const void *value,
1024
             CK_ULONG value_length)
1025
0
{
1026
0
  CK_BYTE byte_value = 0;
1027
1028
  /* Check if value can be converted to CK_BYTE. */
1029
0
  if (value_length > sizeof (CK_BYTE)) {
1030
0
    p11_buffer_fail (buffer);
1031
0
    return;
1032
0
  }
1033
0
  if (value)
1034
0
    memcpy (&byte_value, value, value_length);
1035
1036
0
  p11_rpc_buffer_add_byte (buffer, byte_value);
1037
0
}
1038
1039
void
1040
p11_rpc_buffer_add_ulong_value (p11_buffer *buffer,
1041
        const void *value,
1042
        CK_ULONG value_length)
1043
0
{
1044
0
  CK_ULONG ulong_value = 0;
1045
1046
  /* Check if value can be converted to CK_ULONG. */
1047
0
  if (value_length > sizeof (CK_ULONG)) {
1048
0
    p11_buffer_fail (buffer);
1049
0
    return;
1050
0
  }
1051
0
  if (value)
1052
0
    memcpy (&ulong_value, value, value_length);
1053
1054
  /* Check if ulong_value can be converted to uint64_t. */
1055
0
  if (ulong_value > UINT64_MAX) {
1056
0
    p11_buffer_fail (buffer);
1057
0
    return;
1058
0
  }
1059
1060
0
  p11_rpc_buffer_add_uint64 (buffer, ulong_value);
1061
0
}
1062
1063
void
1064
p11_rpc_buffer_add_attribute_array_value (p11_buffer *buffer,
1065
            const void *value,
1066
            CK_ULONG value_length)
1067
0
{
1068
0
  const CK_ATTRIBUTE *attrs = value;
1069
0
  size_t count = value_length / sizeof (CK_ATTRIBUTE);
1070
0
  size_t i;
1071
1072
  /* Check if count can be converted to uint32_t. */
1073
0
  if (count > UINT32_MAX) {
1074
0
    p11_buffer_fail (buffer);
1075
0
    return;
1076
0
  }
1077
1078
  /* When value is NULL, write an empty attribute array */
1079
0
  if (attrs == NULL) {
1080
0
    p11_rpc_buffer_add_uint32 (buffer, 0);
1081
0
    return;
1082
0
  }
1083
1084
  /* Write the number of items */
1085
0
  p11_rpc_buffer_add_uint32 (buffer, count);
1086
1087
  /* Actually write the attributes.  */
1088
0
  for (i = 0; i < count; i++) {
1089
0
    const CK_ATTRIBUTE *attr = &(attrs[i]);
1090
0
    p11_rpc_buffer_add_attribute (buffer, attr);
1091
0
  }
1092
0
}
1093
1094
void
1095
p11_rpc_buffer_add_mechanism_type_array_value (p11_buffer *buffer,
1096
                 const void *value,
1097
                 CK_ULONG value_length)
1098
0
{
1099
0
  size_t count = value_length / sizeof (CK_MECHANISM_TYPE);
1100
1101
  /* Check if count can be converted to uint32_t. */
1102
0
  if (count > UINT32_MAX) {
1103
0
    p11_buffer_fail (buffer);
1104
0
    return;
1105
0
  }
1106
1107
  /* Write the number of items */
1108
0
  p11_rpc_buffer_add_uint32 (buffer, count);
1109
1110
0
  if (value) {
1111
0
    const CK_MECHANISM_TYPE *mechs = value;
1112
0
    size_t i;
1113
1114
0
    for (i = 0; i < count; i++) {
1115
0
      if (mechs[i] > UINT64_MAX) {
1116
0
        p11_buffer_fail (buffer);
1117
0
        return;
1118
0
      }
1119
0
      p11_rpc_buffer_add_uint64 (buffer, mechs[i]);
1120
0
    }
1121
0
  }
1122
0
}
1123
1124
void
1125
p11_rpc_buffer_add_date_value (p11_buffer *buffer,
1126
             const void *value,
1127
             CK_ULONG value_length)
1128
0
{
1129
0
  CK_DATE date_value;
1130
0
  unsigned char array[8];
1131
0
  unsigned char *ptr = NULL;
1132
1133
  /* Check if value is empty or can be converted to CK_DATE. */
1134
0
  if (value_length != 0 && value_length != sizeof (CK_DATE)) {
1135
0
    p11_buffer_fail (buffer);
1136
0
    return;
1137
0
  }
1138
1139
0
  if (value && value_length == sizeof (CK_DATE)) {
1140
0
    memcpy (&date_value, value, value_length);
1141
0
    memcpy (array, date_value.year, 4);
1142
0
    memcpy (array + 4, date_value.month, 2);
1143
0
    memcpy (array + 6, date_value.day, 2);
1144
0
    ptr = array;
1145
0
  }
1146
1147
0
  p11_rpc_buffer_add_byte_array (buffer, ptr, value_length);
1148
0
}
1149
1150
void
1151
p11_rpc_buffer_add_byte_array_value (p11_buffer *buffer,
1152
             const void *value,
1153
             CK_ULONG value_length)
1154
0
{
1155
  /* Check if value length can be converted to uint32_t, as
1156
   * p11_rpc_buffer_add_byte_array expects. */
1157
0
  if (value_length > UINT32_MAX) {
1158
0
    p11_buffer_fail (buffer);
1159
0
    return;
1160
0
  }
1161
1162
0
  p11_rpc_buffer_add_byte_array (buffer, value, value_length);
1163
0
}
1164
1165
void
1166
p11_rpc_buffer_add_attribute (p11_buffer *buffer, const CK_ATTRIBUTE *attr)
1167
0
{
1168
0
  unsigned char validity;
1169
0
  p11_rpc_attribute_serializer *serializer;
1170
0
  p11_rpc_value_type value_type;
1171
1172
  /* The attribute type */
1173
0
  if (attr->type > UINT32_MAX) {
1174
0
    p11_buffer_fail (buffer);
1175
0
    return;
1176
0
  }
1177
0
  p11_rpc_buffer_add_uint32 (buffer, attr->type);
1178
1179
  /* Write out the attribute validity */
1180
0
  validity = (((CK_LONG)attr->ulValueLen) == -1) ? 0 : 1;
1181
0
  p11_rpc_buffer_add_byte (buffer, validity);
1182
1183
0
  if (!validity)
1184
0
    return;
1185
1186
  /* The attribute length */
1187
0
  if (attr->ulValueLen > UINT32_MAX) {
1188
0
    p11_buffer_fail (buffer);
1189
0
    return;
1190
0
  }
1191
0
  p11_rpc_buffer_add_uint32 (buffer, attr->ulValueLen);
1192
1193
  /* The attribute value */
1194
0
  value_type = map_attribute_to_value_type (attr->type);
1195
0
  assert (value_type < ELEMS (p11_rpc_attribute_serializers));
1196
0
  serializer = &p11_rpc_attribute_serializers[value_type];
1197
0
  assert (serializer != NULL);
1198
0
  serializer->encode (buffer, attr->pValue, attr->ulValueLen);
1199
0
}
1200
1201
bool
1202
p11_rpc_buffer_get_byte_value (p11_buffer *buffer,
1203
             size_t *offset,
1204
             void *value,
1205
             CK_ULONG *value_length)
1206
6
{
1207
6
  unsigned char val;
1208
1209
6
  if (!p11_rpc_buffer_get_byte (buffer, offset, &val))
1210
0
    return false;
1211
1212
6
  if (value) {
1213
3
    CK_BYTE byte_value = val;
1214
3
    memcpy (value, &byte_value, sizeof (CK_BYTE));
1215
3
  }
1216
1217
6
  if (value_length)
1218
3
    *value_length = sizeof (CK_BYTE);
1219
1220
6
  return true;
1221
6
}
1222
1223
bool
1224
p11_rpc_buffer_get_ulong_value (p11_buffer *buffer,
1225
        size_t *offset,
1226
        void *value,
1227
        CK_ULONG *value_length)
1228
450
{
1229
450
  uint64_t val;
1230
1231
450
  if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val))
1232
0
    return false;
1233
1234
450
  if (value) {
1235
413
    CK_ULONG ulong_value = val;
1236
413
    memcpy (value, &ulong_value, sizeof (CK_ULONG));
1237
413
  }
1238
1239
450
  if (value_length)
1240
425
    *value_length = sizeof (CK_ULONG);
1241
1242
450
  return true;
1243
450
}
1244
1245
bool
1246
p11_rpc_buffer_get_attribute_array_value (p11_buffer *buffer,
1247
            size_t *offset,
1248
            void *value,
1249
            CK_ULONG *value_length)
1250
0
{
1251
0
  return p11_rpc_message_get_attribute_array_value (NULL, buffer, offset, value, value_length);
1252
0
}
1253
1254
bool
1255
p11_rpc_buffer_get_mechanism_type_array_value (p11_buffer *buffer,
1256
                 size_t *offset,
1257
                 void *value,
1258
                 CK_ULONG *value_length)
1259
40
{
1260
40
  uint32_t count, i;
1261
40
  CK_MECHANISM_TYPE *mech, temp;
1262
1263
40
  if (!p11_rpc_buffer_get_uint32 (buffer, offset, &count))
1264
0
    return false;
1265
1266
40
  if (!value) {
1267
20
    memset (&temp, 0, sizeof (CK_MECHANISM_TYPE));
1268
20
    mech = &temp;
1269
20
  } else
1270
20
    mech = value;
1271
1272
428
  for (i = 0; i < count; i++) {
1273
388
    CK_ULONG len;
1274
388
    if (!p11_rpc_buffer_get_ulong_value (buffer, offset, mech, &len))
1275
0
      return false;
1276
388
    if (value)
1277
194
      mech++;
1278
388
  }
1279
1280
40
  if (value_length)
1281
20
    *value_length = count * sizeof (CK_MECHANISM_TYPE);
1282
1283
40
  return true;
1284
40
}
1285
1286
bool
1287
p11_rpc_buffer_get_date_value (p11_buffer *buffer,
1288
             size_t *offset,
1289
             void *value,
1290
             CK_ULONG *value_length)
1291
0
{
1292
0
  CK_DATE date_value = { 0 };
1293
0
  const unsigned char *array;
1294
0
  size_t array_length;
1295
1296
  /* The encoded date may be empty. */
1297
0
  if (!p11_rpc_buffer_get_byte_array (buffer, offset,
1298
0
              &array, &array_length) ||
1299
0
      (array_length != 0 && array_length != sizeof (CK_DATE)))
1300
0
    return false;
1301
1302
0
  if (value && array_length == sizeof (CK_DATE)) {
1303
0
    memcpy (date_value.year, array, 4);
1304
0
    memcpy (date_value.month, array + 4, 2);
1305
0
    memcpy (date_value.day, array + 6, 2);
1306
0
    memcpy (value, &date_value, sizeof (CK_DATE));
1307
0
  }
1308
1309
0
  if (value_length)
1310
0
    *value_length = array_length;
1311
1312
0
  return true;
1313
0
}
1314
1315
bool
1316
p11_rpc_buffer_get_byte_array_value (p11_buffer *buffer,
1317
             size_t *offset,
1318
             void *value,
1319
             CK_ULONG *value_length)
1320
430
{
1321
430
  const unsigned char *val;
1322
430
  size_t len;
1323
1324
430
  if (!p11_rpc_buffer_get_byte_array (buffer, offset, &val, &len))
1325
8
    return false;
1326
1327
422
  if (val && value)
1328
36
    memcpy (value, val, len);
1329
1330
422
  if (value_length)
1331
386
    *value_length = len;
1332
1333
422
  return true;
1334
430
}
1335
1336
bool
1337
p11_rpc_message_get_attribute (p11_rpc_message *msg,
1338
             p11_buffer *buffer,
1339
             size_t *offset,
1340
             CK_ATTRIBUTE *attr)
1341
1.19k
{
1342
1.19k
  uint32_t type, length;
1343
1.19k
  CK_ULONG decode_length;
1344
1.19k
  size_t saved_offset;
1345
1.19k
  unsigned char validity;
1346
1.19k
  p11_rpc_attribute_serializer *serializer;
1347
1.19k
  p11_rpc_value_type value_type;
1348
1349
  /* The attribute type */
1350
1.19k
  if (!p11_rpc_buffer_get_uint32 (buffer, offset, &type))
1351
0
    return false;
1352
1353
  /* Attribute validity */
1354
1.19k
  if (!p11_rpc_buffer_get_byte (buffer, offset, &validity))
1355
0
    return false;
1356
1357
  /* Not a valid attribute */
1358
1.19k
  if (!validity) {
1359
735
    attr->ulValueLen = ((CK_ULONG)-1);
1360
735
    attr->type = type;
1361
735
    return true;
1362
735
  }
1363
1364
459
  if (!p11_rpc_buffer_get_uint32 (buffer, offset, &length))
1365
0
    return false;
1366
1367
459
  if (length == 0) {
1368
351
    attr->pValue = NULL;
1369
351
  } else if (msg != NULL) {
1370
    /* Allocate memory for the attribute value */
1371
108
    attr->pValue = p11_rpc_message_alloc_extra (msg, length);
1372
108
    if (attr->pValue == NULL)
1373
1
      return false;
1374
108
  }
1375
1376
458
  value_type = map_attribute_to_value_type (type);
1377
458
  assert (value_type < ELEMS (p11_rpc_attribute_serializers));
1378
458
  serializer = &p11_rpc_attribute_serializers[value_type];
1379
458
  assert (serializer != NULL);
1380
1381
  /* Get the attribute value length */
1382
458
  saved_offset = *offset;
1383
458
  if (!serializer->decode (NULL, buffer, offset, NULL, &decode_length))
1384
8
    return false;
1385
1386
  /* Decode the attribute value */
1387
450
  if (attr->pValue != NULL) {
1388
100
    if (length < decode_length)
1389
12
      return false;
1390
1391
88
    *offset = saved_offset;
1392
88
    if (!serializer->decode (msg, buffer, offset, attr->pValue, NULL))
1393
4
      return false;
1394
88
  }
1395
1396
434
  attr->type = type;
1397
434
  attr->ulValueLen = length;
1398
434
  return true;
1399
450
}
1400
1401
bool
1402
p11_rpc_buffer_get_attribute (p11_buffer *buffer,
1403
            size_t *offset,
1404
            CK_ATTRIBUTE *attr)
1405
0
{
1406
0
  return p11_rpc_message_get_attribute (NULL, buffer, offset, attr);
1407
0
}
1408
1409
/* Used to override the supported mechanisms in tests */
1410
CK_MECHANISM_TYPE *p11_rpc_mechanisms_override_supported = NULL;
1411
1412
typedef struct {
1413
  CK_MECHANISM_TYPE type;
1414
  p11_rpc_value_encoder encode;
1415
  p11_rpc_value_decoder decode;
1416
} p11_rpc_mechanism_serializer;
1417
1418
void
1419
p11_rpc_buffer_add_rsa_pkcs_pss_mechanism_value (p11_buffer *buffer,
1420
             const void *value,
1421
             CK_ULONG value_length)
1422
0
{
1423
0
  CK_RSA_PKCS_PSS_PARAMS params;
1424
1425
  /* Check if value can be converted to CK_RSA_PKCS_PSS_PARAMS. */
1426
0
  if (value_length != sizeof (CK_RSA_PKCS_PSS_PARAMS)) {
1427
0
    p11_buffer_fail (buffer);
1428
0
    return;
1429
0
  }
1430
1431
0
  memcpy (&params, value, value_length);
1432
1433
  /* Check if params.hashAlg, params.mgf, and params.sLen can be
1434
   * converted to uint64_t. */
1435
0
  if (params.hashAlg > UINT64_MAX || params.mgf > UINT64_MAX ||
1436
0
      params.sLen > UINT64_MAX) {
1437
0
    p11_buffer_fail (buffer);
1438
0
    return;
1439
0
  }
1440
1441
0
  p11_rpc_buffer_add_uint64 (buffer, params.hashAlg);
1442
0
  p11_rpc_buffer_add_uint64 (buffer, params.mgf);
1443
0
  p11_rpc_buffer_add_uint64 (buffer, params.sLen);
1444
0
}
1445
1446
bool
1447
p11_rpc_buffer_get_rsa_pkcs_pss_mechanism_value (p11_buffer *buffer,
1448
             size_t *offset,
1449
             void *value,
1450
             CK_ULONG *value_length)
1451
8
{
1452
8
  uint64_t val[3];
1453
1454
8
  if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val[0]))
1455
0
    return false;
1456
8
  if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val[1]))
1457
0
    return false;
1458
8
  if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val[2]))
1459
0
    return false;
1460
1461
8
  if (value) {
1462
4
    CK_RSA_PKCS_PSS_PARAMS params;
1463
1464
4
    params.hashAlg = val[0];
1465
4
    params.mgf = val[1];
1466
4
    params.sLen = val[2];
1467
1468
4
    memcpy (value, &params, sizeof (CK_RSA_PKCS_PSS_PARAMS));
1469
4
  }
1470
1471
8
  if (value_length)
1472
8
    *value_length = sizeof (CK_RSA_PKCS_PSS_PARAMS);
1473
1474
8
  return true;
1475
8
}
1476
1477
void
1478
p11_rpc_buffer_add_rsa_pkcs_oaep_mechanism_value (p11_buffer *buffer,
1479
              const void *value,
1480
              CK_ULONG value_length)
1481
0
{
1482
0
  CK_RSA_PKCS_OAEP_PARAMS params;
1483
1484
  /* Check if value can be converted to CK_RSA_PKCS_OAEP_PARAMS. */
1485
0
  if (value_length != sizeof (CK_RSA_PKCS_OAEP_PARAMS)) {
1486
0
    p11_buffer_fail (buffer);
1487
0
    return;
1488
0
  }
1489
1490
0
  memcpy (&params, value, value_length);
1491
1492
  /* Check if params.hashAlg, params.mgf, and params.source can be
1493
   * converted to uint64_t. */
1494
0
  if (params.hashAlg > UINT64_MAX || params.mgf > UINT64_MAX ||
1495
0
      params.source > UINT64_MAX) {
1496
0
    p11_buffer_fail (buffer);
1497
0
    return;
1498
0
  }
1499
1500
0
  p11_rpc_buffer_add_uint64 (buffer, params.hashAlg);
1501
0
  p11_rpc_buffer_add_uint64 (buffer, params.mgf);
1502
0
  p11_rpc_buffer_add_uint64 (buffer, params.source);
1503
1504
  /* parmas.pSourceData can only be an array of CK_BYTE or
1505
   * NULL */
1506
0
  p11_rpc_buffer_add_byte_array (buffer,
1507
0
               (unsigned char *)params.pSourceData,
1508
0
               params.ulSourceDataLen);
1509
0
}
1510
1511
bool
1512
p11_rpc_buffer_get_rsa_pkcs_oaep_mechanism_value (p11_buffer *buffer,
1513
              size_t *offset,
1514
              void *value,
1515
              CK_ULONG *value_length)
1516
0
{
1517
0
  uint64_t val[3];
1518
0
  const unsigned char *data;
1519
0
  size_t len;
1520
1521
0
  if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val[0]))
1522
0
    return false;
1523
0
  if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val[1]))
1524
0
    return false;
1525
0
  if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val[2]))
1526
0
    return false;
1527
0
  if (!p11_rpc_buffer_get_byte_array (buffer, offset, &data, &len))
1528
0
    return false;
1529
1530
0
  if (value) {
1531
0
    CK_RSA_PKCS_OAEP_PARAMS params;
1532
1533
0
    params.hashAlg = val[0];
1534
0
    params.mgf = val[1];
1535
0
    params.source = val[2];
1536
0
    params.pSourceData = (void *) data;
1537
0
    params.ulSourceDataLen = len;
1538
1539
0
    memcpy (value, &params, sizeof (CK_RSA_PKCS_OAEP_PARAMS));
1540
0
  }
1541
1542
0
  if (value_length)
1543
0
    *value_length = sizeof (CK_RSA_PKCS_OAEP_PARAMS);
1544
1545
0
  return true;
1546
0
}
1547
1548
void
1549
p11_rpc_buffer_add_ecdh1_derive_mechanism_value (p11_buffer *buffer,
1550
             const void *value,
1551
             CK_ULONG value_length)
1552
0
{
1553
0
  CK_ECDH1_DERIVE_PARAMS params;
1554
1555
  /* Check if value can be converted to CK_ECDH1_DERIVE_PARAMS. */
1556
0
  if (value_length != sizeof (CK_ECDH1_DERIVE_PARAMS)) {
1557
0
    p11_buffer_fail (buffer);
1558
0
    return;
1559
0
  }
1560
1561
0
  memcpy (&params, value, value_length);
1562
1563
  /* Check if params.kdf can be converted to uint64_t. */
1564
0
  if (params.kdf > UINT64_MAX) {
1565
0
    p11_buffer_fail (buffer);
1566
0
    return;
1567
0
  }
1568
1569
0
  p11_rpc_buffer_add_uint64 (buffer, params.kdf);
1570
1571
  /* parmas.pSharedData can only be an array of CK_BYTE or
1572
   * NULL */
1573
0
  p11_rpc_buffer_add_byte_array (buffer,
1574
0
               (unsigned char *)params.pSharedData,
1575
0
               params.ulSharedDataLen);
1576
1577
  /* parmas.pPublicData can only be an array of CK_BYTE or
1578
   * NULL */
1579
0
  p11_rpc_buffer_add_byte_array (buffer,
1580
0
               (unsigned char *)params.pPublicData,
1581
0
               params.ulPublicDataLen);
1582
0
}
1583
1584
bool
1585
p11_rpc_buffer_get_ecdh1_derive_mechanism_value (p11_buffer *buffer,
1586
             size_t *offset,
1587
             void *value,
1588
             CK_ULONG *value_length)
1589
10
{
1590
10
  uint64_t val;
1591
10
  const unsigned char *data1, *data2;
1592
10
  size_t len1, len2;
1593
1594
10
  if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val))
1595
0
    return false;
1596
1597
10
  if (!p11_rpc_buffer_get_byte_array (buffer, offset, &data1, &len1))
1598
0
    return false;
1599
1600
10
  if (!p11_rpc_buffer_get_byte_array (buffer, offset, &data2, &len2))
1601
0
    return false;
1602
1603
1604
10
  if (value) {
1605
5
    CK_ECDH1_DERIVE_PARAMS params;
1606
1607
5
    params.kdf = val;
1608
5
    params.pSharedData = (void *) data1;
1609
5
    params.ulSharedDataLen = len1;
1610
5
    params.pPublicData = (void *) data2;
1611
5
    params.ulPublicDataLen = len2;
1612
1613
5
    memcpy (value, &params, sizeof (CK_ECDH1_DERIVE_PARAMS));
1614
5
  }
1615
1616
10
  if (value_length)
1617
10
    *value_length = sizeof (CK_ECDH1_DERIVE_PARAMS);
1618
1619
10
  return true;
1620
10
}
1621
1622
void
1623
p11_rpc_buffer_add_ibm_attrbound_wrap_mechanism_value (p11_buffer *buffer,
1624
                   const void *value,
1625
                   CK_ULONG value_length)
1626
0
{
1627
0
  CK_IBM_ATTRIBUTEBOUND_WRAP_PARAMS params;
1628
1629
  /* Check if value can be converted to CKM_IBM_ATTRIBUTEBOUND_WRAP. */
1630
0
  if (value_length != sizeof (CK_IBM_ATTRIBUTEBOUND_WRAP_PARAMS)) {
1631
0
    p11_buffer_fail (buffer);
1632
0
    return;
1633
0
  }
1634
1635
0
  memcpy (&params, value, value_length);
1636
1637
  /* Check if params.hSignVerifyKey can be converted to uint64_t. */
1638
0
  if (params.hSignVerifyKey > UINT64_MAX) {
1639
0
    p11_buffer_fail (buffer);
1640
0
    return;
1641
0
  }
1642
1643
0
  p11_rpc_buffer_add_uint64 (buffer, params.hSignVerifyKey);
1644
0
}
1645
1646
bool
1647
p11_rpc_buffer_get_ibm_attrbound_wrap_mechanism_value (p11_buffer *buffer,
1648
                   size_t *offset,
1649
                   void *value,
1650
                   CK_ULONG *value_length)
1651
0
{
1652
0
  uint64_t val = 0;
1653
1654
0
  if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val))
1655
0
    return false;
1656
1657
0
  if (value) {
1658
0
    CK_IBM_ATTRIBUTEBOUND_WRAP_PARAMS params = { 0 };
1659
1660
0
    params.hSignVerifyKey = val;
1661
1662
0
    memcpy (value, &params, sizeof (CK_IBM_ATTRIBUTEBOUND_WRAP_PARAMS));
1663
0
  }
1664
1665
0
  if (value_length)
1666
0
    *value_length = sizeof (CK_IBM_ATTRIBUTEBOUND_WRAP_PARAMS);
1667
1668
0
  return true;
1669
0
}
1670
1671
void
1672
p11_rpc_buffer_add_ibm_kyber_mech_param_update (p11_buffer *buffer,
1673
           const void *value,
1674
           CK_ULONG value_length)
1675
0
{
1676
0
  CK_IBM_KYBER_PARAMS params;
1677
1678
0
  if (value_length != sizeof (CK_IBM_KYBER_PARAMS)) {
1679
0
    p11_buffer_fail (buffer);
1680
0
    return;
1681
0
  }
1682
1683
0
  memcpy (&params, value, value_length);
1684
1685
0
  if (params.mode == CK_IBM_KYBER_KEM_ENCAPSULATE) {
1686
0
    p11_rpc_buffer_add_byte(buffer, CK_IBM_KYBER_KEM_ENCAPSULATE);
1687
1688
0
    if (params.pCipher == NULL) {
1689
0
      p11_rpc_buffer_add_byte(buffer, 0);
1690
0
      p11_rpc_buffer_add_uint32(buffer, params.ulCipherLen);
1691
0
    } else {
1692
0
      p11_rpc_buffer_add_byte(buffer, 1);
1693
0
      p11_rpc_buffer_add_byte_array(buffer, (unsigned char *)params.pCipher, params.ulCipherLen);
1694
0
    }
1695
0
  } else {
1696
0
    p11_rpc_buffer_add_byte(buffer, CK_IBM_KYBER_KEM_DECAPSULATE);
1697
0
  }
1698
0
}
1699
1700
bool
1701
p11_rpc_buffer_get_ibm_kyber_mech_param_update (p11_buffer *buffer,
1702
           size_t *offset,
1703
           void *value,
1704
           CK_ULONG *value_length)
1705
0
{
1706
0
  const unsigned char *data;
1707
0
  size_t len;
1708
0
  unsigned char has_data;
1709
0
  unsigned char capsulation;
1710
0
  uint32_t length;
1711
1712
0
  if (!p11_rpc_buffer_get_byte(buffer, offset, &capsulation))
1713
0
    return false;
1714
1715
0
  if (capsulation == CK_IBM_KYBER_KEM_ENCAPSULATE) {
1716
0
    if (!p11_rpc_buffer_get_byte(buffer, offset, &has_data))
1717
0
      return false;
1718
1719
0
    if (has_data == 0) {
1720
0
      if (!p11_rpc_buffer_get_uint32(buffer, offset, &length))
1721
0
        return false;
1722
0
      len = length;
1723
0
    } else {
1724
0
      if (!p11_rpc_buffer_get_byte_array(buffer, offset, &data, &len))
1725
0
        return false;
1726
0
    }
1727
1728
0
    if (value) {
1729
0
      CK_IBM_KYBER_PARAMS *params = (CK_IBM_KYBER_PARAMS *) value;
1730
1731
0
      if (params->pCipher && params->ulCipherLen == len) {
1732
0
        memcpy(params->pCipher, data, len);
1733
0
        params->ulCipherLen = len;
1734
0
      } else {
1735
0
        params->pCipher = (void *) data;
1736
0
        params->ulCipherLen = len;
1737
0
      }
1738
0
    }
1739
0
  }
1740
1741
0
  if (value_length)
1742
0
    *value_length = sizeof (CK_IBM_KYBER_PARAMS);
1743
1744
0
  return true;
1745
0
}
1746
1747
void
1748
p11_rpc_buffer_add_ibm_btc_derive_mech_param_update (p11_buffer *buffer,
1749
           const void *value,
1750
           CK_ULONG value_length)
1751
0
{
1752
0
  CK_IBM_BTC_DERIVE_PARAMS params;
1753
1754
0
  if (value_length != sizeof (CK_IBM_BTC_DERIVE_PARAMS)) {
1755
0
    p11_buffer_fail (buffer);
1756
0
    return;
1757
0
  }
1758
1759
0
  memcpy (&params, value, value_length);
1760
1761
0
  if (params.pChainCode == NULL) {
1762
0
    p11_rpc_buffer_add_byte(buffer, 0);
1763
0
    p11_rpc_buffer_add_uint32(buffer, params.ulChainCodeLen);
1764
0
  } else {
1765
0
    p11_rpc_buffer_add_byte(buffer, 1);
1766
0
    p11_rpc_buffer_add_byte_array(buffer, (unsigned char *)params.pChainCode, params.ulChainCodeLen);
1767
0
  }
1768
0
}
1769
1770
bool
1771
p11_rpc_buffer_get_ibm_btc_derive_mech_param_update (p11_buffer *buffer,
1772
           size_t *offset,
1773
           void *value,
1774
           CK_ULONG *value_length)
1775
0
{
1776
0
  const unsigned char *data;
1777
0
  unsigned char has_data;
1778
0
  size_t len;
1779
0
  uint32_t length;
1780
1781
0
  if (!p11_rpc_buffer_get_byte(buffer, offset, &has_data))
1782
0
    return false;
1783
1784
0
  if (has_data == 0) {
1785
0
    if (!p11_rpc_buffer_get_uint32(buffer, offset, &length))
1786
0
      return false;
1787
0
    len = length;
1788
0
  } else {
1789
0
    if (!p11_rpc_buffer_get_byte_array(buffer, offset, &data, &len))
1790
0
      return false;
1791
0
  }
1792
1793
0
  if (value) {
1794
0
    CK_IBM_BTC_DERIVE_PARAMS *params = (CK_IBM_BTC_DERIVE_PARAMS *) value;
1795
1796
0
    if (params->pChainCode && params->ulChainCodeLen == len) {
1797
0
      memcpy(params->pChainCode, data, len);
1798
0
      params->ulChainCodeLen = len;
1799
0
    } else {
1800
0
      params->pChainCode = (void *) data;
1801
0
      params->ulChainCodeLen = len;
1802
0
    }
1803
0
  }
1804
1805
0
  if (value_length)
1806
0
    *value_length = sizeof (CK_IBM_BTC_DERIVE_PARAMS);
1807
1808
0
  return true;
1809
0
}
1810
1811
void
1812
p11_rpc_buffer_add_ibm_ecdsa_other_mechanism_value (p11_buffer *buffer,
1813
                const void *value,
1814
                CK_ULONG value_length)
1815
0
{
1816
0
  CK_IBM_ECDSA_OTHER_PARAMS params;
1817
1818
0
  if (value_length != sizeof (CK_IBM_ECDSA_OTHER_PARAMS)) {
1819
0
    p11_buffer_fail (buffer);
1820
0
    return;
1821
0
  }
1822
1823
0
  memcpy (&params, value, value_length);
1824
1825
0
  if (params.submechanism > UINT64_MAX) {
1826
0
    p11_buffer_fail (buffer);
1827
0
    return;
1828
0
  }
1829
1830
0
  p11_rpc_buffer_add_uint64 (buffer, params.submechanism);
1831
0
}
1832
1833
bool
1834
p11_rpc_buffer_get_ibm_ecdsa_other_mechanism_value (p11_buffer *buffer,
1835
              size_t *offset,
1836
              void *value,
1837
              CK_ULONG *value_length)
1838
0
{
1839
0
  uint64_t val1;
1840
1841
0
  if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val1))
1842
0
    return false;
1843
1844
0
  if (value) {
1845
0
    CK_IBM_ECDSA_OTHER_PARAMS params;
1846
1847
0
    params.submechanism = val1;
1848
1849
0
    memcpy (value, &params, sizeof (CK_IBM_ECDSA_OTHER_PARAMS));
1850
0
  }
1851
1852
0
  if (value_length)
1853
0
    *value_length = sizeof (CK_IBM_ECDSA_OTHER_PARAMS);
1854
1855
0
  return true;
1856
0
}
1857
1858
void
1859
p11_rpc_buffer_add_ibm_btc_derive_mechanism_value (p11_buffer *buffer,
1860
                   const void *value,
1861
                   CK_ULONG value_length)
1862
0
{
1863
0
  CK_IBM_BTC_DERIVE_PARAMS params;
1864
1865
0
  if (value_length != sizeof (CK_IBM_BTC_DERIVE_PARAMS)) {
1866
0
    p11_buffer_fail (buffer);
1867
0
    return;
1868
0
  }
1869
1870
0
  memcpy (&params, value, value_length);
1871
1872
0
  if (params.type > UINT64_MAX) {
1873
0
    p11_buffer_fail (buffer);
1874
0
    return;
1875
0
  }
1876
0
  p11_rpc_buffer_add_uint64(buffer, params.type);
1877
1878
0
  if (params.childKeyIndex > UINT64_MAX) {
1879
0
    p11_buffer_fail (buffer);
1880
0
    return;
1881
0
  }
1882
0
  p11_rpc_buffer_add_uint64(buffer, params.childKeyIndex);
1883
1884
0
  p11_rpc_buffer_add_byte_array(buffer, (unsigned char *)params.pChainCode, params.ulChainCodeLen);
1885
1886
0
  if (params.version > UINT64_MAX) {
1887
0
    p11_buffer_fail (buffer);
1888
0
    return;
1889
0
  }
1890
0
  p11_rpc_buffer_add_uint64(buffer, params.version);
1891
0
}
1892
1893
bool
1894
p11_rpc_buffer_get_ibm_btc_derive_mechanism_value (p11_buffer *buffer,
1895
               size_t *offset,
1896
               void *value,
1897
               CK_ULONG *value_length)
1898
10
{
1899
10
  uint64_t val1;
1900
10
  uint64_t val2;
1901
10
  size_t len;
1902
10
  const unsigned char *data;
1903
10
  uint64_t val3;
1904
1905
10
  if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val1) ||
1906
10
      !p11_rpc_buffer_get_uint64 (buffer, offset, &val2) ||
1907
10
      !p11_rpc_buffer_get_byte_array (buffer, offset, &data, &len) ||
1908
10
      !p11_rpc_buffer_get_uint64 (buffer, offset, &val3))
1909
0
    return false;
1910
1911
10
  if (value) {
1912
5
    CK_IBM_BTC_DERIVE_PARAMS params = { 0 };
1913
1914
5
    params.type = val1;
1915
5
    params.childKeyIndex = val2;
1916
5
    params.ulChainCodeLen = len;
1917
5
    params.pChainCode = (void *) data;
1918
5
    params.version = val3;
1919
1920
5
    memcpy (value, &params, sizeof (CK_IBM_BTC_DERIVE_PARAMS));
1921
5
  }
1922
1923
10
  if (value_length)
1924
10
    *value_length = sizeof (CK_IBM_BTC_DERIVE_PARAMS);
1925
1926
10
  return true;
1927
10
}
1928
1929
void
1930
p11_rpc_buffer_add_ibm_kyber_mechanism_value (p11_buffer *buffer,
1931
                const void *value,
1932
                CK_ULONG value_length)
1933
0
{
1934
0
  CK_IBM_KYBER_PARAMS params;
1935
1936
0
  if (value_length != sizeof (CK_IBM_KYBER_PARAMS)) {
1937
0
    p11_buffer_fail (buffer);
1938
0
    return;
1939
0
  }
1940
1941
0
  memcpy (&params, value, value_length);
1942
1943
0
  if (params.ulVersion > UINT64_MAX) {
1944
0
    p11_buffer_fail (buffer);
1945
0
    return;
1946
0
  }
1947
0
  p11_rpc_buffer_add_uint64(buffer, params.ulVersion);
1948
1949
0
  if (params.mode > UINT64_MAX) {
1950
0
    p11_buffer_fail (buffer);
1951
0
    return;
1952
0
  }
1953
0
  p11_rpc_buffer_add_uint64(buffer, params.mode);
1954
1955
0
  if (params.kdf > UINT64_MAX) {
1956
0
    p11_buffer_fail (buffer);
1957
0
    return;
1958
0
  }
1959
0
  p11_rpc_buffer_add_uint64(buffer, params.kdf);
1960
1961
0
  if (params.bPrepend > sizeof(CK_BBOOL)) {
1962
0
    p11_buffer_fail(buffer);
1963
0
    return;
1964
0
  }
1965
0
  p11_rpc_buffer_add_byte(buffer, (unsigned char) params.bPrepend);
1966
1967
0
  p11_rpc_buffer_add_byte_array(buffer, (unsigned char *)params.pCipher, params.ulCipherLen);
1968
1969
0
  p11_rpc_buffer_add_byte_array(buffer, (unsigned char *)params.pSharedData, params.ulSharedDataLen);
1970
1971
0
  if (params.hSecret > sizeof(CK_OBJECT_HANDLE)) {
1972
0
    p11_buffer_fail(buffer);
1973
0
    return;
1974
0
  }
1975
0
  p11_rpc_buffer_add_uint64(buffer, params.hSecret);
1976
0
}
1977
1978
bool
1979
p11_rpc_buffer_get_ibm_kyber_mechanism_value (p11_buffer *buffer,
1980
                size_t *offset,
1981
                void *value,
1982
                CK_ULONG *value_length)
1983
2
{
1984
2
  uint64_t val1;
1985
2
  uint64_t val2;
1986
2
  uint64_t val3;
1987
2
  unsigned char byte;
1988
2
  const unsigned char *data1;
1989
2
  size_t len1;
1990
2
  const unsigned char *data2;
1991
2
  size_t len2;
1992
2
  uint64_t val4;
1993
1994
2
  if (!p11_rpc_buffer_get_uint64(buffer, offset, &val1) ||
1995
2
      !p11_rpc_buffer_get_uint64(buffer, offset, &val2) ||
1996
2
      !p11_rpc_buffer_get_uint64(buffer, offset, &val3) ||
1997
2
      !p11_rpc_buffer_get_byte(buffer, offset, &byte) ||
1998
2
      !p11_rpc_buffer_get_byte_array(buffer, offset, &data1, &len1) ||
1999
2
      !p11_rpc_buffer_get_byte_array(buffer, offset, &data2, &len2) ||
2000
2
      !p11_rpc_buffer_get_uint64(buffer, offset, &val4))
2001
0
    return false;
2002
2003
2
  if (value) {
2004
1
    CK_IBM_KYBER_PARAMS *params = (CK_IBM_KYBER_PARAMS *) value;
2005
2006
1
    params->ulVersion = val1;
2007
1
    params->mode = val2;
2008
1
    params->kdf = val3;
2009
1
    params->bPrepend = byte;
2010
1
    if (params->pCipher && params->ulCipherLen == len1) {
2011
0
      memcpy(params->pCipher, data1, len1);
2012
0
      params->ulCipherLen = len1;
2013
1
    } else {
2014
1
      params->pCipher = (void *) data1;
2015
1
      params->ulCipherLen = len1;
2016
1
    }
2017
1
    if (params->pSharedData && params->ulSharedDataLen == len2) {
2018
0
      memcpy(params->pSharedData, data2, len2);
2019
0
      params->ulSharedDataLen = len2;
2020
1
    } else {
2021
1
      params->pSharedData = (void *) data2;
2022
1
      params->ulSharedDataLen = len2;
2023
1
    }
2024
1
    params->hSecret = val4;
2025
1
  }
2026
2027
2
  if (value_length)
2028
2
    *value_length = sizeof (CK_IBM_KYBER_PARAMS);
2029
2030
2
  return true;
2031
2
}
2032
2033
void
2034
p11_rpc_buffer_add_aes_iv_mechanism_value (p11_buffer *buffer,
2035
             const void *value,
2036
             CK_ULONG value_length)
2037
0
{
2038
  /* Check if value can be converted to an AES IV. */
2039
0
  if (value_length != 16) {
2040
0
    p11_buffer_fail (buffer);
2041
0
    return;
2042
0
  }
2043
2044
0
  p11_rpc_buffer_add_byte_array (buffer,
2045
0
               (unsigned char *)value,
2046
0
               value_length);
2047
0
}
2048
2049
bool
2050
p11_rpc_buffer_get_aes_iv_mechanism_value (p11_buffer *buffer,
2051
             size_t *offset,
2052
             void *value,
2053
             CK_ULONG *value_length)
2054
0
{
2055
0
  const unsigned char *data;
2056
0
  size_t len;
2057
2058
0
  if (!p11_rpc_buffer_get_byte_array (buffer, offset, &data, &len))
2059
0
    return false;
2060
2061
0
  if (len != 16)
2062
0
    return false;
2063
2064
0
  if (value)
2065
0
    memcpy (value, data, len);
2066
2067
0
  if (value_length)
2068
0
    *value_length = len;
2069
2070
0
  return true;
2071
0
}
2072
2073
void
2074
p11_rpc_buffer_add_aes_ctr_mechanism_value (p11_buffer *buffer,
2075
              const void *value,
2076
              CK_ULONG value_length)
2077
0
{
2078
0
  CK_AES_CTR_PARAMS params;
2079
2080
  /* Check if value can be converted to CK_AES_CTR_PARAMS. */
2081
0
  if (value_length != sizeof (CK_AES_CTR_PARAMS)) {
2082
0
    p11_buffer_fail (buffer);
2083
0
    return;
2084
0
  }
2085
2086
0
  memcpy (&params, value, value_length);
2087
2088
  /* Check if params.ulCounterBits can be converted to uint64_t. */
2089
0
  if (params.ulCounterBits > UINT64_MAX) {
2090
0
    p11_buffer_fail (buffer);
2091
0
    return;
2092
0
  }
2093
2094
0
  p11_rpc_buffer_add_uint64 (buffer, params.ulCounterBits);
2095
2096
0
  p11_rpc_buffer_add_byte_array (buffer,
2097
0
               (unsigned char *)params.cb,
2098
0
               sizeof(params.cb));
2099
0
}
2100
2101
bool
2102
p11_rpc_buffer_get_aes_ctr_mechanism_value (p11_buffer *buffer,
2103
              size_t *offset,
2104
              void *value,
2105
              CK_ULONG *value_length)
2106
0
{
2107
0
  uint64_t val;
2108
0
  const unsigned char *data;
2109
0
  size_t len;
2110
2111
0
  if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val))
2112
0
    return false;
2113
0
  if (!p11_rpc_buffer_get_byte_array (buffer, offset, &data, &len))
2114
0
    return false;
2115
2116
0
  if (value) {
2117
0
    CK_AES_CTR_PARAMS params;
2118
2119
0
    params.ulCounterBits = val;
2120
2121
0
    if (len != sizeof (params.cb))
2122
0
      return false;
2123
2124
0
    memcpy (params.cb, data, sizeof (params.cb));
2125
0
    memcpy (value, &params, sizeof (CK_AES_CTR_PARAMS));
2126
0
  }
2127
2128
0
  if (value_length)
2129
0
    *value_length = sizeof (CK_AES_CTR_PARAMS);
2130
2131
0
  return true;
2132
0
}
2133
2134
void
2135
p11_rpc_buffer_add_aes_gcm_mechanism_value (p11_buffer *buffer,
2136
              const void *value,
2137
              CK_ULONG value_length)
2138
0
{
2139
0
  CK_GCM_PARAMS params;
2140
2141
  /* Check if value can be converted to CK_GCM_PARAMS. */
2142
0
  if (value_length != sizeof (CK_GCM_PARAMS)) {
2143
0
    p11_buffer_fail (buffer);
2144
0
    return;
2145
0
  }
2146
2147
0
  memcpy (&params, value, value_length);
2148
2149
  /* Check if params.ulTagBits/ulIvBits can be converted to uint64_t. */
2150
0
  if (params.ulTagBits > UINT64_MAX || params.ulIvBits > UINT64_MAX) {
2151
0
    p11_buffer_fail (buffer);
2152
0
    return;
2153
0
  }
2154
2155
0
  p11_rpc_buffer_add_byte_array (buffer,
2156
0
               (unsigned char *)params.pIv,
2157
0
               params.ulIvLen);
2158
0
  p11_rpc_buffer_add_uint64 (buffer, params.ulIvBits);
2159
0
  p11_rpc_buffer_add_byte_array (buffer,
2160
0
               (unsigned char *)params.pAAD,
2161
0
               params.ulAADLen);
2162
0
  p11_rpc_buffer_add_uint64 (buffer, params.ulTagBits);
2163
0
}
2164
2165
bool
2166
p11_rpc_buffer_get_aes_gcm_mechanism_value (p11_buffer *buffer,
2167
              size_t *offset,
2168
              void *value,
2169
              CK_ULONG *value_length)
2170
0
{
2171
0
  uint64_t val1, val2;
2172
0
  const unsigned char *data1, *data2;
2173
0
  size_t len1, len2;
2174
2175
0
  if (!p11_rpc_buffer_get_byte_array (buffer, offset, &data1, &len1))
2176
0
    return false;
2177
0
  if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val1))
2178
0
    return false;
2179
0
  if (!p11_rpc_buffer_get_byte_array (buffer, offset, &data2, &len2))
2180
0
    return false;
2181
0
  if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val2))
2182
0
    return false;
2183
2184
0
  if (value) {
2185
0
    CK_GCM_PARAMS params;
2186
2187
0
    params.pIv = (void *) data1;
2188
0
    params.ulIvLen = len1;
2189
0
    params.ulIvBits = val1;
2190
0
    params.pAAD = (void *) data2;
2191
0
    params.ulAADLen = len2;
2192
0
    params.ulTagBits = val2;
2193
2194
0
    memcpy (value, &params, sizeof (CK_GCM_PARAMS));
2195
0
  }
2196
2197
0
  if (value_length)
2198
0
    *value_length = sizeof (CK_GCM_PARAMS);
2199
2200
0
  return true;
2201
0
}
2202
2203
void
2204
p11_rpc_buffer_add_des_iv_mechanism_value (p11_buffer *buffer,
2205
             const void *value,
2206
             CK_ULONG value_length)
2207
0
{
2208
  /* Check if value can be converted to an DES IV. */
2209
0
  if (value_length != 8) {
2210
0
    p11_buffer_fail (buffer);
2211
0
    return;
2212
0
  }
2213
2214
0
  p11_rpc_buffer_add_byte_array (buffer,
2215
0
               (unsigned char *)value,
2216
0
               value_length);
2217
0
}
2218
2219
bool
2220
p11_rpc_buffer_get_des_iv_mechanism_value (p11_buffer *buffer,
2221
             size_t *offset,
2222
             void *value,
2223
             CK_ULONG *value_length)
2224
1
{
2225
1
  const unsigned char *data;
2226
1
  size_t len;
2227
2228
1
  if (!p11_rpc_buffer_get_byte_array (buffer, offset, &data, &len))
2229
1
    return false;
2230
2231
0
  if (len != 8)
2232
0
    return false;
2233
2234
0
  if (value)
2235
0
    memcpy (value, data, len);
2236
2237
0
  if (value_length)
2238
0
    *value_length = len;
2239
2240
0
  return true;
2241
0
}
2242
2243
void
2244
p11_rpc_buffer_add_mac_general_mechanism_value (p11_buffer *buffer,
2245
            const void *value,
2246
            CK_ULONG value_length)
2247
0
{
2248
0
  CK_ULONG val;
2249
0
  uint64_t params;
2250
2251
  /*
2252
   * Check if value can be converted to an CK_MAC_GENERAL_PARAMS which
2253
   * is a CK_ULONG.
2254
   */
2255
0
  if (value_length != sizeof (CK_ULONG)) {
2256
0
    p11_buffer_fail (buffer);
2257
0
    return;
2258
0
  }
2259
2260
0
  memcpy (&val, value, value_length);
2261
0
  params = val;
2262
2263
0
  p11_rpc_buffer_add_uint64 (buffer, params);
2264
0
}
2265
2266
bool
2267
p11_rpc_buffer_get_mac_general_mechanism_value (p11_buffer *buffer,
2268
            size_t *offset,
2269
            void *value,
2270
            CK_ULONG *value_length)
2271
0
{
2272
0
  uint64_t val;
2273
0
  CK_ULONG params;
2274
2275
0
  if (!p11_rpc_buffer_get_uint64 (buffer, offset, &val))
2276
0
    return false;
2277
2278
0
  params = val;
2279
2280
0
  if (value)
2281
0
    memcpy (value, &params, sizeof (params));
2282
2283
0
  if (value_length)
2284
0
    *value_length = sizeof (params);
2285
2286
0
  return true;
2287
0
}
2288
2289
void
2290
p11_rpc_buffer_add_dh_pkcs_derive_mechanism_value (p11_buffer *buffer,
2291
               const void *value,
2292
               CK_ULONG value_length)
2293
0
{
2294
  /* Mechanism parameter is public value of the other party */
2295
0
  if (value_length == 0) {
2296
0
    p11_buffer_fail (buffer);
2297
0
    return;
2298
0
  }
2299
2300
0
  p11_rpc_buffer_add_byte_array (buffer,
2301
0
               (unsigned char *)value,
2302
0
               value_length);
2303
0
}
2304
2305
bool
2306
p11_rpc_buffer_get_dh_pkcs_derive_mechanism_value (p11_buffer *buffer,
2307
               size_t *offset,
2308
               void *value,
2309
               CK_ULONG *value_length)
2310
1
{
2311
1
  const unsigned char *data;
2312
1
  size_t len;
2313
2314
1
  if (!p11_rpc_buffer_get_byte_array (buffer, offset, &data, &len))
2315
0
    return false;
2316
2317
1
  if (len == 0)
2318
1
    return false;
2319
2320
0
  if (value)
2321
0
    memcpy (value, data, len);
2322
2323
0
  if (value_length)
2324
0
    *value_length = len;
2325
2326
0
  return true;
2327
1
}
2328
2329
static p11_rpc_mechanism_serializer p11_rpc_mech_param_update_serializers[] = {
2330
  { CKM_IBM_BTC_DERIVE, p11_rpc_buffer_add_ibm_btc_derive_mech_param_update, p11_rpc_buffer_get_ibm_btc_derive_mech_param_update },
2331
  { CKM_IBM_KYBER, p11_rpc_buffer_add_ibm_kyber_mech_param_update, p11_rpc_buffer_get_ibm_kyber_mech_param_update },
2332
};
2333
2334
static p11_rpc_mechanism_serializer p11_rpc_mechanism_serializers[] = {
2335
  { CKM_IBM_ECDSA_OTHER, p11_rpc_buffer_add_ibm_ecdsa_other_mechanism_value, p11_rpc_buffer_get_ibm_ecdsa_other_mechanism_value },
2336
  { CKM_IBM_BTC_DERIVE, p11_rpc_buffer_add_ibm_btc_derive_mechanism_value, p11_rpc_buffer_get_ibm_btc_derive_mechanism_value },
2337
  { CKM_IBM_KYBER, p11_rpc_buffer_add_ibm_kyber_mechanism_value, p11_rpc_buffer_get_ibm_kyber_mechanism_value },
2338
  { CKM_RSA_PKCS_PSS, p11_rpc_buffer_add_rsa_pkcs_pss_mechanism_value, p11_rpc_buffer_get_rsa_pkcs_pss_mechanism_value },
2339
  { CKM_SHA1_RSA_PKCS_PSS, p11_rpc_buffer_add_rsa_pkcs_pss_mechanism_value, p11_rpc_buffer_get_rsa_pkcs_pss_mechanism_value },
2340
  { CKM_SHA224_RSA_PKCS_PSS, p11_rpc_buffer_add_rsa_pkcs_pss_mechanism_value, p11_rpc_buffer_get_rsa_pkcs_pss_mechanism_value },
2341
  { CKM_SHA256_RSA_PKCS_PSS, p11_rpc_buffer_add_rsa_pkcs_pss_mechanism_value, p11_rpc_buffer_get_rsa_pkcs_pss_mechanism_value },
2342
  { CKM_SHA384_RSA_PKCS_PSS, p11_rpc_buffer_add_rsa_pkcs_pss_mechanism_value, p11_rpc_buffer_get_rsa_pkcs_pss_mechanism_value },
2343
  { CKM_SHA512_RSA_PKCS_PSS, p11_rpc_buffer_add_rsa_pkcs_pss_mechanism_value, p11_rpc_buffer_get_rsa_pkcs_pss_mechanism_value },
2344
  { CKM_RSA_PKCS_OAEP, p11_rpc_buffer_add_rsa_pkcs_oaep_mechanism_value, p11_rpc_buffer_get_rsa_pkcs_oaep_mechanism_value },
2345
  { CKM_ECDH1_DERIVE, p11_rpc_buffer_add_ecdh1_derive_mechanism_value, p11_rpc_buffer_get_ecdh1_derive_mechanism_value },
2346
  { CKM_IBM_ATTRIBUTEBOUND_WRAP, p11_rpc_buffer_add_ibm_attrbound_wrap_mechanism_value, p11_rpc_buffer_get_ibm_attrbound_wrap_mechanism_value },
2347
  { CKM_IBM_EC_X25519, p11_rpc_buffer_add_ecdh1_derive_mechanism_value, p11_rpc_buffer_get_ecdh1_derive_mechanism_value },
2348
  { CKM_IBM_EC_X448, p11_rpc_buffer_add_ecdh1_derive_mechanism_value, p11_rpc_buffer_get_ecdh1_derive_mechanism_value },
2349
  { CKM_AES_CBC, p11_rpc_buffer_add_aes_iv_mechanism_value, p11_rpc_buffer_get_aes_iv_mechanism_value },
2350
  { CKM_AES_CBC_PAD, p11_rpc_buffer_add_aes_iv_mechanism_value, p11_rpc_buffer_get_aes_iv_mechanism_value },
2351
  { CKM_AES_OFB, p11_rpc_buffer_add_aes_iv_mechanism_value, p11_rpc_buffer_get_aes_iv_mechanism_value },
2352
  { CKM_AES_CFB1, p11_rpc_buffer_add_aes_iv_mechanism_value, p11_rpc_buffer_get_aes_iv_mechanism_value },
2353
  { CKM_AES_CFB8, p11_rpc_buffer_add_aes_iv_mechanism_value, p11_rpc_buffer_get_aes_iv_mechanism_value },
2354
  { CKM_AES_CFB64, p11_rpc_buffer_add_aes_iv_mechanism_value, p11_rpc_buffer_get_aes_iv_mechanism_value },
2355
  { CKM_AES_CFB128, p11_rpc_buffer_add_aes_iv_mechanism_value, p11_rpc_buffer_get_aes_iv_mechanism_value },
2356
  { CKM_AES_CTS, p11_rpc_buffer_add_aes_iv_mechanism_value, p11_rpc_buffer_get_aes_iv_mechanism_value },
2357
  { CKM_AES_CTR, p11_rpc_buffer_add_aes_ctr_mechanism_value, p11_rpc_buffer_get_aes_ctr_mechanism_value },
2358
  { CKM_AES_GCM, p11_rpc_buffer_add_aes_gcm_mechanism_value, p11_rpc_buffer_get_aes_gcm_mechanism_value },
2359
  { CKM_DES_CBC, p11_rpc_buffer_add_des_iv_mechanism_value, p11_rpc_buffer_get_des_iv_mechanism_value },
2360
  { CKM_DES_CBC_PAD, p11_rpc_buffer_add_des_iv_mechanism_value, p11_rpc_buffer_get_des_iv_mechanism_value },
2361
  { CKM_DES3_CBC, p11_rpc_buffer_add_des_iv_mechanism_value, p11_rpc_buffer_get_des_iv_mechanism_value },
2362
  { CKM_DES3_CBC_PAD, p11_rpc_buffer_add_des_iv_mechanism_value, p11_rpc_buffer_get_des_iv_mechanism_value },
2363
  { CKM_DES_CFB8, p11_rpc_buffer_add_des_iv_mechanism_value, p11_rpc_buffer_get_des_iv_mechanism_value },
2364
  { CKM_DES_CFB64, p11_rpc_buffer_add_des_iv_mechanism_value, p11_rpc_buffer_get_des_iv_mechanism_value },
2365
  { CKM_DES_OFB64, p11_rpc_buffer_add_des_iv_mechanism_value, p11_rpc_buffer_get_des_iv_mechanism_value },
2366
  { CKM_SHA_1_HMAC_GENERAL, p11_rpc_buffer_add_mac_general_mechanism_value, p11_rpc_buffer_get_mac_general_mechanism_value },
2367
  { CKM_SHA224_HMAC_GENERAL, p11_rpc_buffer_add_mac_general_mechanism_value, p11_rpc_buffer_get_mac_general_mechanism_value },
2368
  { CKM_SHA256_HMAC_GENERAL, p11_rpc_buffer_add_mac_general_mechanism_value, p11_rpc_buffer_get_mac_general_mechanism_value },
2369
  { CKM_SHA384_HMAC_GENERAL, p11_rpc_buffer_add_mac_general_mechanism_value, p11_rpc_buffer_get_mac_general_mechanism_value },
2370
  { CKM_SHA512_HMAC_GENERAL, p11_rpc_buffer_add_mac_general_mechanism_value, p11_rpc_buffer_get_mac_general_mechanism_value },
2371
  { CKM_SHA512_224_HMAC_GENERAL, p11_rpc_buffer_add_mac_general_mechanism_value, p11_rpc_buffer_get_mac_general_mechanism_value },
2372
  { CKM_SHA512_256_HMAC_GENERAL, p11_rpc_buffer_add_mac_general_mechanism_value, p11_rpc_buffer_get_mac_general_mechanism_value },
2373
  { CKM_AES_MAC_GENERAL, p11_rpc_buffer_add_mac_general_mechanism_value, p11_rpc_buffer_get_mac_general_mechanism_value },
2374
  { CKM_AES_CMAC_GENERAL, p11_rpc_buffer_add_mac_general_mechanism_value, p11_rpc_buffer_get_mac_general_mechanism_value },
2375
  { CKM_DES3_MAC_GENERAL, p11_rpc_buffer_add_mac_general_mechanism_value, p11_rpc_buffer_get_mac_general_mechanism_value },
2376
  { CKM_DES3_CMAC_GENERAL, p11_rpc_buffer_add_mac_general_mechanism_value, p11_rpc_buffer_get_mac_general_mechanism_value },
2377
  { CKM_DH_PKCS_DERIVE, p11_rpc_buffer_add_dh_pkcs_derive_mechanism_value, p11_rpc_buffer_get_dh_pkcs_derive_mechanism_value },
2378
};
2379
2380
static p11_rpc_mechanism_serializer p11_rpc_byte_array_mechanism_serializer = {
2381
  0, p11_rpc_buffer_add_byte_array_value, p11_rpc_buffer_get_byte_array_value
2382
};
2383
2384
static bool
2385
mechanism_has_sane_parameters (CK_MECHANISM_TYPE type)
2386
0
{
2387
0
  int i;
2388
2389
  /* This can be set from tests, to override default set of supported */
2390
0
  if (p11_rpc_mechanisms_override_supported) {
2391
0
    for (i = 0; p11_rpc_mechanisms_override_supported[i] != 0; i++) {
2392
0
      if (p11_rpc_mechanisms_override_supported[i] == type)
2393
0
        return true;
2394
0
    }
2395
2396
0
    return false;
2397
0
  }
2398
2399
0
  for (i = 0; i < ELEMS(p11_rpc_mechanism_serializers); i++) {
2400
0
    if (p11_rpc_mechanism_serializers[i].type == type)
2401
0
      return true;
2402
0
  }
2403
2404
0
  return false;
2405
0
}
2406
2407
static bool
2408
mechanism_has_no_parameters (CK_MECHANISM_TYPE mech)
2409
34
{
2410
  /* This list is incomplete */
2411
2412
34
  switch (mech) {
2413
0
  case CKM_RSA_PKCS_KEY_PAIR_GEN:
2414
0
  case CKM_RSA_X9_31_KEY_PAIR_GEN:
2415
0
  case CKM_RSA_PKCS:
2416
0
  case CKM_RSA_9796:
2417
0
  case CKM_RSA_X_509:
2418
0
  case CKM_RSA_X9_31:
2419
0
  case CKM_MD2_RSA_PKCS:
2420
0
  case CKM_MD5_RSA_PKCS:
2421
0
  case CKM_SHA1_RSA_PKCS:
2422
0
  case CKM_SHA224_RSA_PKCS:
2423
0
  case CKM_SHA256_RSA_PKCS:
2424
0
  case CKM_SHA384_RSA_PKCS:
2425
0
  case CKM_SHA512_RSA_PKCS:
2426
0
  case CKM_RIPEMD128_RSA_PKCS:
2427
0
  case CKM_RIPEMD160_RSA_PKCS:
2428
0
  case CKM_SHA1_RSA_X9_31:
2429
0
  case CKM_DSA_KEY_PAIR_GEN:
2430
0
  case CKM_DSA_PARAMETER_GEN:
2431
0
  case CKM_DSA:
2432
0
  case CKM_DSA_SHA1:
2433
0
  case CKM_FORTEZZA_TIMESTAMP:
2434
0
  case CKM_EC_KEY_PAIR_GEN:
2435
0
  case CKM_ECDSA:
2436
0
  case CKM_ECDSA_SHA1:
2437
0
  case CKM_ECDSA_SHA224:
2438
0
  case CKM_ECDSA_SHA256:
2439
0
  case CKM_ECDSA_SHA384:
2440
0
  case CKM_ECDSA_SHA512:
2441
0
  case CKM_DH_PKCS_KEY_PAIR_GEN:
2442
0
  case CKM_DH_PKCS_PARAMETER_GEN:
2443
0
  case CKM_X9_42_DH_KEY_PAIR_GEN:
2444
0
  case CKM_X9_42_DH_PARAMETER_GEN:
2445
0
  case CKM_KEA_KEY_PAIR_GEN:
2446
0
  case CKM_GENERIC_SECRET_KEY_GEN:
2447
0
  case CKM_RC2_KEY_GEN:
2448
0
  case CKM_RC4_KEY_GEN:
2449
0
  case CKM_RC4:
2450
0
  case CKM_RC5_KEY_GEN:
2451
0
  case CKM_AES_KEY_GEN:
2452
0
  case CKM_AES_ECB:
2453
0
  case CKM_AES_MAC:
2454
0
  case CKM_AES_CMAC:
2455
0
  case CKM_DES_KEY_GEN:
2456
0
  case CKM_DES2_KEY_GEN:
2457
0
  case CKM_DES3_KEY_GEN:
2458
0
  case CKM_CDMF_KEY_GEN:
2459
0
  case CKM_CAST_KEY_GEN:
2460
0
  case CKM_CAST3_KEY_GEN:
2461
0
  case CKM_CAST128_KEY_GEN:
2462
0
  case CKM_IDEA_KEY_GEN:
2463
0
  case CKM_SSL3_PRE_MASTER_KEY_GEN:
2464
0
  case CKM_TLS_PRE_MASTER_KEY_GEN:
2465
0
  case CKM_SKIPJACK_KEY_GEN:
2466
0
  case CKM_BATON_KEY_GEN:
2467
0
  case CKM_JUNIPER_KEY_GEN:
2468
0
  case CKM_RC2_ECB:
2469
0
  case CKM_DES_ECB:
2470
0
  case CKM_DES3_ECB:
2471
0
  case CKM_CDMF_ECB:
2472
0
  case CKM_CAST_ECB:
2473
0
  case CKM_CAST3_ECB:
2474
0
  case CKM_CAST128_ECB:
2475
0
  case CKM_RC5_ECB:
2476
0
  case CKM_IDEA_ECB:
2477
0
  case CKM_RC2_MAC:
2478
0
  case CKM_DES_MAC:
2479
0
  case CKM_DES3_MAC:
2480
0
  case CKM_DES3_CMAC:
2481
0
  case CKM_CDMF_MAC:
2482
0
  case CKM_CAST_MAC:
2483
0
  case CKM_CAST3_MAC:
2484
0
  case CKM_RC5_MAC:
2485
0
  case CKM_IDEA_MAC:
2486
0
  case CKM_SSL3_MD5_MAC:
2487
0
  case CKM_SSL3_SHA1_MAC:
2488
0
  case CKM_SKIPJACK_WRAP:
2489
0
  case CKM_BATON_WRAP:
2490
0
  case CKM_JUNIPER_WRAP:
2491
0
  case CKM_MD2:
2492
0
  case CKM_MD2_HMAC:
2493
0
  case CKM_MD5:
2494
0
  case CKM_MD5_HMAC:
2495
0
  case CKM_SHA_1:
2496
0
  case CKM_SHA_1_HMAC:
2497
0
  case CKM_SHA1_KEY_DERIVATION:
2498
0
  case CKM_SHA224:
2499
0
  case CKM_SHA224_HMAC:
2500
0
  case CKM_SHA224_KEY_DERIVATION:
2501
0
  case CKM_SHA256:
2502
0
  case CKM_SHA256_HMAC:
2503
0
  case CKM_SHA256_KEY_DERIVATION:
2504
0
  case CKM_SHA384:
2505
0
  case CKM_SHA384_HMAC:
2506
0
  case CKM_SHA384_KEY_DERIVATION:
2507
0
  case CKM_SHA512:
2508
0
  case CKM_SHA512_HMAC:
2509
0
  case CKM_SHA512_KEY_DERIVATION:
2510
0
  case CKM_SHA512_T:
2511
0
  case CKM_SHA512_T_HMAC:
2512
0
  case CKM_SHA512_T_KEY_DERIVATION:
2513
0
  case CKM_SHA512_224:
2514
0
  case CKM_SHA512_224_HMAC:
2515
0
  case CKM_SHA512_224_KEY_DERIVATION:
2516
0
  case CKM_SHA512_256:
2517
0
  case CKM_SHA512_256_HMAC:
2518
0
  case CKM_SHA512_256_KEY_DERIVATION:
2519
0
  case CKM_FASTHASH:
2520
0
  case CKM_RIPEMD128:
2521
0
  case CKM_RIPEMD128_HMAC:
2522
0
  case CKM_RIPEMD160:
2523
0
  case CKM_RIPEMD160_HMAC:
2524
0
  case CKM_KEY_WRAP_LYNKS:
2525
0
  case CKM_IBM_SHA3_224:
2526
0
  case CKM_IBM_SHA3_256:
2527
0
  case CKM_IBM_SHA3_384:
2528
0
  case CKM_IBM_SHA3_512:
2529
0
  case CKM_IBM_CMAC:
2530
0
  case CKM_IBM_DILITHIUM:
2531
0
  case CKM_IBM_SHA3_224_HMAC:
2532
0
  case CKM_IBM_SHA3_256_HMAC:
2533
0
  case CKM_IBM_SHA3_384_HMAC:
2534
0
  case CKM_IBM_SHA3_512_HMAC:
2535
0
  case CKM_IBM_ED25519_SHA512:
2536
0
  case CKM_IBM_ED448_SHA3:
2537
0
    return true;
2538
34
  default:
2539
34
    return false;
2540
34
  };
2541
0
}
2542
2543
bool
2544
p11_rpc_mechanism_is_supported (CK_MECHANISM_TYPE mech)
2545
0
{
2546
0
  if (mechanism_has_no_parameters (mech) ||
2547
0
      mechanism_has_sane_parameters (mech))
2548
0
    return true;
2549
0
  return false;
2550
0
}
2551
2552
void
2553
p11_rpc_buffer_add_mechanism (p11_buffer *buffer, const CK_MECHANISM *mech)
2554
0
{
2555
0
  p11_rpc_mechanism_serializer *serializer = NULL;
2556
0
  size_t i;
2557
2558
  /* The mechanism type */
2559
0
  p11_rpc_buffer_add_uint32 (buffer, mech->mechanism);
2560
2561
0
  if (mechanism_has_no_parameters (mech->mechanism)) {
2562
0
    return;
2563
0
  }
2564
2565
0
  assert (mechanism_has_sane_parameters (mech->mechanism));
2566
2567
0
  if (mech->pParameter == NULL && mech->ulParameterLen == 0) {
2568
0
    p11_rpc_buffer_add_byte (buffer, 0);
2569
0
    return;
2570
0
  } else {
2571
0
    p11_rpc_buffer_add_byte (buffer, 1);
2572
0
  }
2573
2574
0
  for (i = 0; i < ELEMS (p11_rpc_mechanism_serializers); i++) {
2575
0
    if (p11_rpc_mechanism_serializers[i].type == mech->mechanism) {
2576
0
      serializer = &p11_rpc_mechanism_serializers[i];
2577
0
      break;
2578
0
    }
2579
0
  }
2580
2581
0
  if (serializer == NULL)
2582
0
    serializer = &p11_rpc_byte_array_mechanism_serializer;
2583
2584
0
  serializer->encode (buffer, mech->pParameter, mech->ulParameterLen);
2585
0
}
2586
2587
bool
2588
p11_rpc_buffer_get_mechanism (p11_buffer *buffer,
2589
            size_t *offset,
2590
            CK_MECHANISM *mech)
2591
34
{
2592
34
  uint32_t mechanism;
2593
34
  p11_rpc_mechanism_serializer *serializer = NULL;
2594
34
  size_t i;
2595
34
  unsigned char has_param;
2596
2597
  /* The mechanism type */
2598
34
  if (!p11_rpc_buffer_get_uint32 (buffer, offset, &mechanism))
2599
0
    return false;
2600
2601
34
  mech->mechanism = mechanism;
2602
2603
  /*
2604
   * The NULL mechanism is used for C_*Init () functions to
2605
   * cancel operation.  We use a special value 0xffffffff as a
2606
   * marker to indicate that.
2607
   */
2608
34
  if (mechanism == 0xffffffff) {
2609
0
    mech->ulParameterLen = 0;
2610
0
    mech->pParameter = NULL;
2611
0
    return true;
2612
34
  } else if (mechanism_has_no_parameters (mech->mechanism)) {
2613
0
    return true;
2614
0
  }
2615
2616
34
  if (!p11_rpc_buffer_get_byte(buffer, offset, &has_param))
2617
0
    return false;
2618
2619
34
  if (has_param == 0) {
2620
2
    mech->ulParameterLen = 0;
2621
2
    mech->pParameter = NULL;
2622
2
    return true;
2623
2
  }
2624
2625
278
  for (i = 0; i < ELEMS (p11_rpc_mechanism_serializers); i++) {
2626
278
    if (p11_rpc_mechanism_serializers[i].type == mech->mechanism) {
2627
32
      serializer = &p11_rpc_mechanism_serializers[i];
2628
32
      break;
2629
32
    }
2630
278
  }
2631
2632
32
  if (serializer == NULL)
2633
0
    serializer = &p11_rpc_byte_array_mechanism_serializer;
2634
2635
32
  if (!serializer->decode (buffer, offset,
2636
32
         mech->pParameter, &mech->ulParameterLen))
2637
2
    return false;
2638
2639
30
  return true;
2640
32
}
2641
2642
void
2643
p11_rpc_buffer_add_mech_param_update (p11_buffer *buffer, const CK_MECHANISM *mech)
2644
0
{
2645
0
  p11_rpc_mechanism_serializer *serializer = NULL;
2646
0
  size_t i;
2647
2648
0
  if (mechanism_has_no_parameters (mech->mechanism)) {
2649
0
    return;
2650
0
  }
2651
2652
0
  if (mech->pParameter == NULL && mech->ulParameterLen == 0) {
2653
0
    p11_rpc_buffer_add_byte (buffer, 0);
2654
0
    return;
2655
0
  } else {
2656
0
    p11_rpc_buffer_add_byte (buffer, 1);
2657
0
  }
2658
2659
0
  for (i = 0; i < ELEMS (p11_rpc_mech_param_update_serializers); i++) {
2660
0
    if (p11_rpc_mech_param_update_serializers[i].type == mech->mechanism) {
2661
0
      serializer = &p11_rpc_mech_param_update_serializers[i];
2662
0
      break;
2663
0
    }
2664
0
  }
2665
2666
0
  if (serializer == NULL)
2667
0
    return;
2668
2669
0
  serializer->encode (buffer, mech->pParameter, mech->ulParameterLen);
2670
0
}
2671
2672
bool
2673
p11_rpc_buffer_get_mech_param_update (p11_buffer *buffer,
2674
            size_t *offset,
2675
            CK_MECHANISM *mech)
2676
0
{
2677
0
  p11_rpc_mechanism_serializer *serializer = NULL;
2678
0
  size_t i;
2679
0
  unsigned char has_param;
2680
2681
0
  if (mechanism_has_no_parameters (mech->mechanism)) {
2682
0
    mech->ulParameterLen = 0;
2683
0
    mech->pParameter = NULL;
2684
0
    return true;
2685
0
  }
2686
2687
0
  if (!p11_rpc_buffer_get_byte(buffer, offset, &has_param))
2688
0
    return false;
2689
2690
0
  if (has_param == 0) {
2691
0
    mech->ulParameterLen = 0;
2692
0
    mech->pParameter = NULL;
2693
0
    return true;
2694
0
  }
2695
2696
0
  for (i = 0; i < ELEMS (p11_rpc_mech_param_update_serializers); i++) {
2697
0
    if (p11_rpc_mech_param_update_serializers[i].type == mech->mechanism) {
2698
0
      serializer = &p11_rpc_mech_param_update_serializers[i];
2699
0
      break;
2700
0
    }
2701
0
  }
2702
2703
0
  if (serializer == NULL)
2704
0
    return true;
2705
2706
0
  if (!serializer->decode (buffer, offset,
2707
0
         mech->pParameter, &mech->ulParameterLen))
2708
0
    return false;
2709
2710
0
  return true;
2711
0
}