1 /*
2 * COPYRIGHT (c) International Business Machines Corp. 2001-2017
3 *
4 * This program is provided under the terms of the Common Public License,
5 * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
6 * software constitutes recipient's acceptance of CPL-1.0 terms which can be
7 * found in the file LICENSE file or at
8 * https://opensource.org/licenses/cpl1.0.php
9 */
10
11 // File: mech_des.c
12 //
13 // Mechanisms for DES
14 //
15
16 #include <string.h> // for memcmp() et al
17 #include <stdlib.h>
18
19 #include "pkcs11types.h"
20 #include "defs.h"
21 #include "host_defs.h"
22 #include "h_extern.h"
23 #include "tok_spec_struct.h"
24 #include "trace.h"
25
26 #include <openssl/crypto.h>
27
28 //
29 //
pk_des_ecb_encrypt(STDLL_TokData_t * tokdata,SESSION * sess,CK_BBOOL length_only,ENCR_DECR_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len)30 CK_RV pk_des_ecb_encrypt(STDLL_TokData_t *tokdata,
31 SESSION *sess,
32 CK_BBOOL length_only,
33 ENCR_DECR_CONTEXT *ctx,
34 CK_BYTE *in_data,
35 CK_ULONG in_data_len,
36 CK_BYTE *out_data, CK_ULONG *out_data_len)
37 {
38 OBJECT *key = NULL;
39 CK_RV rc;
40
41
42 if (!sess || !ctx || !out_data_len) {
43 TRACE_ERROR("%s received bad argument(s)\n", __func__);
44 return CKR_FUNCTION_FAILED;
45 }
46 // CKM_DES_ECB requires the input data to be an integral
47 // multiple of the block size
48 //
49 if (in_data_len % DES_BLOCK_SIZE != 0) {
50 TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
51 return CKR_DATA_LEN_RANGE;
52 }
53 rc = object_mgr_find_in_map1(tokdata, ctx->key, &key);
54 if (rc != CKR_OK) {
55 TRACE_ERROR("Failed to find specified object.\n");
56 return rc;
57 }
58
59 if (length_only == TRUE) {
60 *out_data_len = in_data_len;
61 return CKR_OK;
62 }
63
64 if (*out_data_len < in_data_len) {
65 *out_data_len = in_data_len;
66 TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
67 return CKR_BUFFER_TOO_SMALL;
68 }
69
70 return ckm_des_ecb_encrypt(tokdata, in_data, in_data_len,
71 out_data, out_data_len, key);
72 }
73
74
75 //
76 //
des_ecb_decrypt(STDLL_TokData_t * tokdata,SESSION * sess,CK_BBOOL length_only,ENCR_DECR_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len)77 CK_RV des_ecb_decrypt(STDLL_TokData_t *tokdata,
78 SESSION *sess,
79 CK_BBOOL length_only,
80 ENCR_DECR_CONTEXT *ctx,
81 CK_BYTE *in_data,
82 CK_ULONG in_data_len,
83 CK_BYTE *out_data, CK_ULONG *out_data_len)
84 {
85 OBJECT *key = NULL;
86 CK_RV rc;
87
88
89 if (!sess || !ctx || !out_data_len) {
90 TRACE_ERROR("%s received bad argument(s)\n", __func__);
91 return CKR_FUNCTION_FAILED;
92 }
93 // CKM_DES_ECB requires the input data to be an integral
94 // multiple of the block size
95 //
96 if (in_data_len % DES_BLOCK_SIZE != 0) {
97 TRACE_ERROR("%s\n", ock_err(ERR_ENCRYPTED_DATA_LEN_RANGE));
98 return CKR_ENCRYPTED_DATA_LEN_RANGE;
99 }
100 rc = object_mgr_find_in_map1(tokdata, ctx->key, &key);
101 if (rc != CKR_OK) {
102 TRACE_ERROR("Failed to find specified object.\n");
103 return rc;
104 }
105
106 if (length_only == TRUE) {
107 *out_data_len = in_data_len;
108 return CKR_OK;
109 }
110
111 if (*out_data_len < in_data_len) {
112 *out_data_len = in_data_len;
113 TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
114 return CKR_BUFFER_TOO_SMALL;
115 }
116
117 return ckm_des_ecb_decrypt(tokdata, in_data, in_data_len,
118 out_data, out_data_len, key);
119 }
120
121
122 //
123 //
pk_des_cbc_encrypt(STDLL_TokData_t * tokdata,SESSION * sess,CK_BBOOL length_only,ENCR_DECR_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len)124 CK_RV pk_des_cbc_encrypt(STDLL_TokData_t *tokdata,
125 SESSION *sess,
126 CK_BBOOL length_only,
127 ENCR_DECR_CONTEXT *ctx,
128 CK_BYTE *in_data,
129 CK_ULONG in_data_len,
130 CK_BYTE *out_data, CK_ULONG *out_data_len)
131 {
132 OBJECT *key = NULL;
133 CK_RV rc;
134
135 if (!sess || !ctx || !out_data_len) {
136 TRACE_ERROR("%s received bad argument(s)\n", __func__);
137 return CKR_FUNCTION_FAILED;
138 }
139 // CKM_DES_CBC requires the input data to be an integral
140 // multiple of the block size
141 //
142 if (in_data_len % DES_BLOCK_SIZE != 0) {
143 TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
144 return CKR_DATA_LEN_RANGE;
145 }
146 rc = object_mgr_find_in_map1(tokdata, ctx->key, &key);
147 if (rc != CKR_OK) {
148 TRACE_ERROR("Failed to find specified object.\n");
149 return rc;
150 }
151
152 if (length_only == TRUE) {
153 *out_data_len = in_data_len;
154 return CKR_OK;
155 }
156
157 if (*out_data_len < in_data_len) {
158 *out_data_len = in_data_len;
159 TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
160 return CKR_BUFFER_TOO_SMALL;
161 }
162
163 return ckm_des_cbc_encrypt(tokdata, in_data, in_data_len, out_data,
164 out_data_len, ctx->mech.pParameter, key);
165 }
166
167
168 //
169 //
des_cbc_decrypt(STDLL_TokData_t * tokdata,SESSION * sess,CK_BBOOL length_only,ENCR_DECR_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len)170 CK_RV des_cbc_decrypt(STDLL_TokData_t *tokdata,
171 SESSION *sess,
172 CK_BBOOL length_only,
173 ENCR_DECR_CONTEXT *ctx,
174 CK_BYTE *in_data,
175 CK_ULONG in_data_len,
176 CK_BYTE *out_data, CK_ULONG *out_data_len)
177 {
178 OBJECT *key = NULL;
179 CK_RV rc;
180
181
182 if (!sess || !ctx || !out_data_len) {
183 TRACE_ERROR("%s received bad argument(s)\n", __func__);
184 return CKR_FUNCTION_FAILED;
185 }
186 // CKM_DES_CBC requires the input data to be an integral
187 // multiple of the block size
188 //
189 if (in_data_len % DES_BLOCK_SIZE != 0) {
190 TRACE_ERROR("%s\n", ock_err(ERR_ENCRYPTED_DATA_LEN_RANGE));
191 return CKR_ENCRYPTED_DATA_LEN_RANGE;
192 }
193 rc = object_mgr_find_in_map1(tokdata, ctx->key, &key);
194 if (rc != CKR_OK) {
195 TRACE_ERROR("Failed to find specified object.\n");
196 return rc;
197 }
198
199 if (length_only == TRUE) {
200 *out_data_len = in_data_len;
201 return CKR_OK;
202 }
203
204 if (*out_data_len < in_data_len) {
205 *out_data_len = in_data_len;
206 TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
207 return CKR_BUFFER_TOO_SMALL;
208 }
209
210 return ckm_des_cbc_decrypt(tokdata, in_data, in_data_len, out_data,
211 out_data_len, ctx->mech.pParameter, key);
212 }
213
214
215 //
216 //
des_cbc_pad_encrypt(STDLL_TokData_t * tokdata,SESSION * sess,CK_BBOOL length_only,ENCR_DECR_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len)217 CK_RV des_cbc_pad_encrypt(STDLL_TokData_t *tokdata,
218 SESSION *sess,
219 CK_BBOOL length_only,
220 ENCR_DECR_CONTEXT *ctx,
221 CK_BYTE *in_data,
222 CK_ULONG in_data_len,
223 CK_BYTE *out_data, CK_ULONG *out_data_len)
224 {
225 OBJECT *key = NULL;
226 CK_BYTE *clear = NULL;
227 CK_ULONG padded_len;
228 CK_RV rc;
229
230 if (!sess || !ctx || !out_data_len) {
231 TRACE_ERROR("%s received bad argument(s)\n", __func__);
232 return CKR_FUNCTION_FAILED;
233 }
234 // DES-CBC-PAD has no input length requirements
235 //
236
237 rc = object_mgr_find_in_map1(tokdata, ctx->key, &key);
238 if (rc != CKR_OK) {
239 TRACE_ERROR("Failed to find specified object.\n");
240 return rc;
241 }
242 // compute the output length, accounting for padding
243 //
244 padded_len = DES_BLOCK_SIZE * (in_data_len / DES_BLOCK_SIZE + 1);
245
246 if (length_only == TRUE) {
247 *out_data_len = padded_len;
248 return CKR_OK;
249 }
250
251 if (*out_data_len < padded_len) {
252 *out_data_len = padded_len;
253 TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
254 return CKR_BUFFER_TOO_SMALL;
255 }
256
257 clear = (CK_BYTE *) malloc(padded_len);
258 if (!clear) {
259 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
260 return CKR_HOST_MEMORY;
261 }
262 memcpy(clear, in_data, in_data_len);
263
264 add_pkcs_padding(clear + in_data_len,
265 DES_BLOCK_SIZE, in_data_len, padded_len);
266
267 rc = ckm_des_cbc_encrypt(tokdata, clear, padded_len, out_data, out_data_len,
268 ctx->mech.pParameter, key);
269 free(clear);
270
271 return rc;
272 }
273
274
275 //
276 //
des_cbc_pad_decrypt(STDLL_TokData_t * tokdata,SESSION * sess,CK_BBOOL length_only,ENCR_DECR_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len)277 CK_RV des_cbc_pad_decrypt(STDLL_TokData_t *tokdata,
278 SESSION *sess,
279 CK_BBOOL length_only,
280 ENCR_DECR_CONTEXT *ctx,
281 CK_BYTE *in_data,
282 CK_ULONG in_data_len,
283 CK_BYTE *out_data, CK_ULONG *out_data_len)
284 {
285 OBJECT *key = NULL;
286 CK_BYTE *clear = NULL;
287 CK_ULONG padded_len;
288 CK_RV rc;
289
290
291 if (!sess || !ctx || !out_data_len) {
292 TRACE_ERROR("%s received bad argument(s)\n", __func__);
293 return CKR_FUNCTION_FAILED;
294 }
295 //
296 // no need to validate the input length since we'll pad as necessary
297 //
298
299 rc = object_mgr_find_in_map1(tokdata, ctx->key, &key);
300 if (rc != CKR_OK) {
301 TRACE_ERROR("Failed to find specified object.\n");
302 return rc;
303 }
304 // we're decrypting so even with CBC-PAD, we should have an integral
305 // number of block to decrypt
306 //
307 if (in_data_len % DES_BLOCK_SIZE != 0) {
308 TRACE_ERROR("%s\n", ock_err(ERR_ENCRYPTED_DATA_LEN_RANGE));
309 return CKR_ENCRYPTED_DATA_LEN_RANGE;
310 }
311 // the amount of cleartext after stripping the padding will actually be less
312 // than the input bytes...
313 //
314 padded_len = in_data_len;
315
316 if (length_only == TRUE) {
317 *out_data_len = padded_len;
318 return CKR_OK;
319 }
320
321 clear = (CK_BYTE *) malloc(padded_len);
322 if (!clear) {
323 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
324 return CKR_HOST_MEMORY;
325 }
326 rc = ckm_des_cbc_decrypt(tokdata, in_data, in_data_len, clear, &padded_len,
327 ctx->mech.pParameter, key);
328
329 if (rc == CKR_OK) {
330 strip_pkcs_padding(clear, padded_len, out_data_len);
331 memcpy(out_data, clear, *out_data_len);
332 }
333
334 free(clear);
335
336 return rc;
337 }
338
339
340 //
341 //
des_ecb_encrypt_update(STDLL_TokData_t * tokdata,SESSION * sess,CK_BBOOL length_only,ENCR_DECR_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len)342 CK_RV des_ecb_encrypt_update(STDLL_TokData_t *tokdata,
343 SESSION *sess,
344 CK_BBOOL length_only,
345 ENCR_DECR_CONTEXT *ctx,
346 CK_BYTE *in_data,
347 CK_ULONG in_data_len,
348 CK_BYTE *out_data, CK_ULONG *out_data_len)
349 {
350 DES_CONTEXT *context = NULL;
351 OBJECT *key = NULL;
352 CK_BYTE *clear = NULL;
353 CK_ULONG total, remain, out_len;
354 CK_RV rc;
355
356 if (!sess || !ctx || !out_data_len) {
357 TRACE_ERROR("%s received bad argument(s)\n", __func__);
358 return CKR_FUNCTION_FAILED;
359 }
360 context = (DES_CONTEXT *) ctx->context;
361
362 total = (context->len + in_data_len);
363
364 if (total < DES_BLOCK_SIZE) {
365 if (length_only == FALSE && in_data_len) {
366 memcpy(context->data + context->len, in_data, in_data_len);
367 context->len += in_data_len;
368 }
369 *out_data_len = 0;
370 return CKR_OK;
371 } else {
372 // we have at least 1 block
373 //
374 remain = (total % DES_BLOCK_SIZE);
375 out_len = (total - remain); // should always be at least 1 block
376
377 if (length_only == TRUE) {
378 *out_data_len = out_len;
379 return CKR_OK;
380 }
381
382 rc = object_mgr_find_in_map_nocache(ctx->key, &key);
383 if (rc != CKR_OK) {
384 TRACE_ERROR("Failed to find specified object.\n");
385 return rc;
386 }
387
388 clear = (CK_BYTE *) malloc(out_len);
389 if (!clear) {
390 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
391 return CKR_HOST_MEMORY;
392 }
393 // copy any data left over from the previous encryption operation first
394 //
395 memcpy(clear, context->data, context->len);
396 memcpy(clear + context->len, in_data, out_len - context->len);
397
398 rc = ckm_des_ecb_encrypt(tokdata, clear, out_len, out_data,
399 out_data_len, key);
400 if (rc == CKR_OK) {
401 *out_data_len = out_len;
402
403 // update the context buffer. we already used the buffer's current
404 // contents so we completely overwrite it
405 //
406 if (remain != 0)
407 memcpy(context->data, in_data + (in_data_len - remain), remain);
408 context->len = remain;
409 }
410 free(clear);
411 return rc;
412 }
413 }
414
415
416 //
417 //
des_ecb_decrypt_update(STDLL_TokData_t * tokdata,SESSION * sess,CK_BBOOL length_only,ENCR_DECR_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len)418 CK_RV des_ecb_decrypt_update(STDLL_TokData_t *tokdata,
419 SESSION *sess,
420 CK_BBOOL length_only,
421 ENCR_DECR_CONTEXT *ctx,
422 CK_BYTE *in_data,
423 CK_ULONG in_data_len,
424 CK_BYTE *out_data, CK_ULONG *out_data_len)
425 {
426 DES_CONTEXT *context = NULL;
427 OBJECT *key = NULL;
428 CK_BYTE *cipher = NULL;
429 CK_ULONG total, remain, out_len;
430 CK_RV rc;
431
432 if (!sess || !ctx || !out_data_len) {
433 TRACE_ERROR("%s received bad argument(s)\n", __func__);
434 return CKR_FUNCTION_FAILED;
435 }
436 context = (DES_CONTEXT *) ctx->context;
437
438 total = (context->len + in_data_len);
439
440 if (total < DES_BLOCK_SIZE) {
441 if (length_only == FALSE && in_data_len) {
442 memcpy(context->data + context->len, in_data, in_data_len);
443 context->len += in_data_len;
444 }
445
446 *out_data_len = 0;
447 return CKR_OK;
448 } else {
449 // we have at least 1 block
450 //
451 remain = (total % DES_BLOCK_SIZE);
452 out_len = total - remain;
453
454 if (length_only == TRUE) {
455 *out_data_len = out_len;
456 return CKR_OK;
457 }
458
459 rc = object_mgr_find_in_map_nocache(ctx->key, &key);
460 if (rc != CKR_OK) {
461 TRACE_ERROR("Failed to find specified object.\n");
462 return rc;
463 }
464
465 cipher = (CK_BYTE *) malloc(out_len);
466 if (!cipher) {
467 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
468 return CKR_HOST_MEMORY;
469 }
470 // copy any data left over from the previous decryption operation first
471 //
472 memcpy(cipher, context->data, context->len);
473 memcpy(cipher + context->len, in_data, out_len - context->len);
474
475 rc = ckm_des_ecb_decrypt(tokdata, cipher, out_len, out_data,
476 out_data_len, key);
477 if (rc == CKR_OK) {
478 *out_data_len = out_len;
479
480 // copy the remaining 'new' input data to the context buffer
481 //
482 if (remain != 0)
483 memcpy(context->data, in_data + (in_data_len - remain), remain);
484 context->len = remain;
485 }
486 free(cipher);
487 return rc;
488 }
489 }
490
491
492 //
493 //
des_cbc_encrypt_update(STDLL_TokData_t * tokdata,SESSION * sess,CK_BBOOL length_only,ENCR_DECR_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len)494 CK_RV des_cbc_encrypt_update(STDLL_TokData_t *tokdata,
495 SESSION *sess,
496 CK_BBOOL length_only,
497 ENCR_DECR_CONTEXT *ctx,
498 CK_BYTE *in_data,
499 CK_ULONG in_data_len,
500 CK_BYTE *out_data, CK_ULONG *out_data_len)
501 {
502 DES_CONTEXT *context = NULL;
503 OBJECT *key = NULL;
504 CK_BYTE *clear = NULL;
505 CK_ULONG total, remain, out_len;
506 CK_RV rc;
507
508
509 if (!sess || !ctx || !out_data_len) {
510 TRACE_ERROR("%s received bad argument(s)\n", __func__);
511 return CKR_FUNCTION_FAILED;
512 }
513 context = (DES_CONTEXT *) ctx->context;
514
515 total = (context->len + in_data_len);
516
517 if (total < DES_BLOCK_SIZE) {
518 if (length_only == FALSE && in_data_len) {
519 memcpy(context->data + context->len, in_data, in_data_len);
520 context->len += in_data_len;
521 }
522
523 *out_data_len = 0;
524 return CKR_OK;
525 } else {
526 // we have at least 1 block
527 //
528 remain = (total % DES_BLOCK_SIZE);
529 out_len = total - remain;
530
531 if (length_only == TRUE) {
532 *out_data_len = out_len;
533 return CKR_OK;
534 }
535
536 rc = object_mgr_find_in_map_nocache(ctx->key, &key);
537 if (rc != CKR_OK) {
538 TRACE_ERROR("Failed to find specified object.\n");
539 return rc;
540 }
541 // these buffers need to be longword aligned
542 //
543 clear = (CK_BYTE *) malloc(out_len);
544 if (!clear) {
545 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
546 return CKR_HOST_MEMORY;
547 }
548 // copy any data left over from the previous encryption operation first
549 //
550 memcpy(clear, context->data, context->len);
551 memcpy(clear + context->len, in_data, out_len - context->len);
552
553 rc = ckm_des_cbc_encrypt(tokdata, clear, out_len, out_data,
554 out_data_len, ctx->mech.pParameter, key);
555 if (rc == CKR_OK) {
556 *out_data_len = out_len;
557
558 // the new init_v is the last encrypted data block
559 //
560 memcpy(ctx->mech.pParameter,
561 out_data + (*out_data_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE);
562
563 // copy the remaining 'new' input data to the context buffer
564 //
565 if (remain != 0)
566 memcpy(context->data, in_data + (in_data_len - remain), remain);
567 context->len = remain;
568 }
569
570 free(clear);
571 return rc;
572 }
573 }
574
575
576 //
577 //
des_cbc_decrypt_update(STDLL_TokData_t * tokdata,SESSION * sess,CK_BBOOL length_only,ENCR_DECR_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len)578 CK_RV des_cbc_decrypt_update(STDLL_TokData_t *tokdata,
579 SESSION *sess,
580 CK_BBOOL length_only,
581 ENCR_DECR_CONTEXT *ctx,
582 CK_BYTE *in_data,
583 CK_ULONG in_data_len,
584 CK_BYTE *out_data, CK_ULONG *out_data_len)
585 {
586 DES_CONTEXT *context = NULL;
587 OBJECT *key = NULL;
588 CK_BYTE *cipher = NULL;
589 CK_ULONG total, remain, out_len;
590 CK_RV rc;
591
592
593 if (!sess || !ctx || !out_data_len) {
594 TRACE_ERROR("%s received bad argument(s)\n", __func__);
595 return CKR_FUNCTION_FAILED;
596 }
597 context = (DES_CONTEXT *) ctx->context;
598
599 total = context->len + in_data_len;
600
601 if (total < DES_BLOCK_SIZE) {
602 if (length_only == FALSE && in_data_len) {
603 memcpy(context->data + context->len, in_data, in_data_len);
604 context->len += in_data_len;
605 }
606
607 *out_data_len = 0;
608 return CKR_OK;
609 } else {
610 // we have at least 1 block
611 //
612 remain = total % DES_BLOCK_SIZE;
613 out_len = total - remain;
614
615 if (length_only == TRUE) {
616 *out_data_len = out_len;
617 return CKR_OK;
618 }
619
620 rc = object_mgr_find_in_map_nocache(ctx->key, &key);
621 if (rc != CKR_OK) {
622 TRACE_ERROR("Failed to find specified object.\n");
623 return rc;
624 }
625 // these buffers need to be longword aligned
626 //
627 cipher = (CK_BYTE *) malloc(out_len);
628 if (!cipher) {
629 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
630 return CKR_HOST_MEMORY;
631 }
632 // copy any data left over from the previous decryption operation first
633 //
634 memcpy(cipher, context->data, context->len);
635 memcpy(cipher + context->len, in_data, out_len - context->len);
636
637 rc = ckm_des_cbc_decrypt(tokdata, cipher, out_len, out_data,
638 out_data_len, ctx->mech.pParameter, key);
639 if (rc == CKR_OK) {
640 *out_data_len = out_len;
641
642 // the new init_v is the last decrypted data block
643 //
644 memcpy(ctx->mech.pParameter, cipher + (out_len - DES_BLOCK_SIZE),
645 DES_BLOCK_SIZE);
646
647 // copy the remaining 'new' input data to the context buffer
648 //
649 if (remain != 0)
650 memcpy(context->data, in_data + (in_data_len - remain), remain);
651 context->len = remain;
652 }
653
654 free(cipher);
655 return rc;
656 }
657 }
658
659
660 //
661 //
des_cbc_pad_encrypt_update(STDLL_TokData_t * tokdata,SESSION * sess,CK_BBOOL length_only,ENCR_DECR_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len)662 CK_RV des_cbc_pad_encrypt_update(STDLL_TokData_t *tokdata,
663 SESSION *sess,
664 CK_BBOOL length_only,
665 ENCR_DECR_CONTEXT *ctx,
666 CK_BYTE *in_data,
667 CK_ULONG in_data_len,
668 CK_BYTE *out_data, CK_ULONG *out_data_len)
669 {
670 DES_CONTEXT *context = NULL;
671 OBJECT *key = NULL;
672 CK_BYTE *clear = NULL;
673 CK_ULONG total, remain, out_len;
674 CK_RV rc;
675
676
677 if (!sess || !ctx || !out_data_len) {
678 TRACE_ERROR("%s received bad argument(s)\n", __func__);
679 return CKR_FUNCTION_FAILED;
680 }
681 context = (DES_CONTEXT *) ctx->context;
682
683 total = (context->len + in_data_len);
684
685 // note, this is subtly different from the other encrypt update routines
686 //
687 if (total <= DES_BLOCK_SIZE) {
688 if (length_only == FALSE) {
689 memcpy(context->data + context->len, in_data, in_data_len);
690 context->len += in_data_len;
691 }
692
693 *out_data_len = 0;
694 return CKR_OK;
695 } else {
696 // we have at least 1 block + 1 byte
697 //
698 remain = total % DES_BLOCK_SIZE;
699 out_len = total - remain;
700
701 if (remain == 0) {
702 remain = DES_BLOCK_SIZE;
703 out_len -= DES_BLOCK_SIZE;
704 }
705
706 if (length_only == TRUE) {
707 *out_data_len = out_len;
708 return CKR_OK;
709 }
710 // at this point, we should have:
711 // 1) remain != 0
712 // 2) out_len != 0
713 //
714 rc = object_mgr_find_in_map_nocache(ctx->key, &key);
715 if (rc != CKR_OK) {
716 TRACE_ERROR("Failed to find specified object.\n");
717 return rc;
718 }
719 // these buffers need to be longword aligned
720 //
721 clear = (CK_BYTE *) malloc(out_len);
722 if (!clear) {
723 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
724 return CKR_HOST_MEMORY;
725 }
726 // copy any data left over from the previous encryption operation first
727 //
728 memcpy(clear, context->data, context->len);
729 memcpy(clear + context->len, in_data, out_len - context->len);
730
731 //
732 // we don't do padding during the update
733 //
734 rc = ckm_des_cbc_encrypt(tokdata, clear, out_len, out_data,
735 out_data_len, ctx->mech.pParameter, key);
736
737 if (rc == CKR_OK) {
738 // the new init_v is the last encrypted data block
739 //
740 memcpy(ctx->mech.pParameter,
741 out_data + (*out_data_len - DES_BLOCK_SIZE), DES_BLOCK_SIZE);
742
743 // copy the remaining 'new' input data to the temporary space
744 //
745 memcpy(context->data, in_data + (in_data_len - remain), remain);
746 context->len = remain;
747 }
748
749 free(clear);
750 return rc;
751 }
752 }
753
754
755 //
756 //
des_cbc_pad_decrypt_update(STDLL_TokData_t * tokdata,SESSION * sess,CK_BBOOL length_only,ENCR_DECR_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len)757 CK_RV des_cbc_pad_decrypt_update(STDLL_TokData_t *tokdata,
758 SESSION *sess,
759 CK_BBOOL length_only,
760 ENCR_DECR_CONTEXT *ctx,
761 CK_BYTE *in_data,
762 CK_ULONG in_data_len,
763 CK_BYTE *out_data, CK_ULONG *out_data_len)
764 {
765 DES_CONTEXT *context = NULL;
766 OBJECT *key = NULL;
767 CK_BYTE *cipher = NULL;
768 CK_ULONG total, remain, out_len;
769 CK_RV rc;
770
771
772 if (!sess || !ctx || !out_data_len) {
773 TRACE_ERROR("%s received bad argument(s)\n", __func__);
774 return CKR_FUNCTION_FAILED;
775 }
776 context = (DES_CONTEXT *) ctx->context;
777
778 total = (context->len + in_data_len);
779
780 // note, this is subtly different from the other decrypt update routines
781 //
782 if (total <= DES_BLOCK_SIZE) {
783 if (length_only == FALSE) {
784 memcpy(context->data + context->len, in_data, in_data_len);
785 context->len += in_data_len;
786 }
787
788 *out_data_len = 0;
789 return CKR_OK;
790 } else {
791 // we have at least 1 block + 1 byte
792 //
793 remain = total % DES_BLOCK_SIZE;
794 out_len = total - remain;
795
796 if (remain == 0) {
797 remain = DES_BLOCK_SIZE;
798 out_len -= DES_BLOCK_SIZE;
799 }
800
801 if (length_only == TRUE) {
802 *out_data_len = out_len;
803 return CKR_OK;
804 }
805 // at this point, we should have:
806 // 1) remain != 0
807 // 2) out_len != 0
808 //
809 rc = object_mgr_find_in_map_nocache(ctx->key, &key);
810 if (rc != CKR_OK) {
811 TRACE_ERROR("Failed to find specified object.\n");
812 return rc;
813 }
814 // these buffers need to be longword aligned
815 //
816 cipher = (CK_BYTE *) malloc(out_len);
817 if (!cipher) {
818 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
819 return CKR_HOST_MEMORY;
820 }
821 // copy any data left over from the previous decryption operation first
822 //
823 memcpy(cipher, context->data, context->len);
824 memcpy(cipher + context->len, in_data, out_len - context->len);
825
826 rc = ckm_des_cbc_decrypt(tokdata, cipher, out_len, out_data,
827 out_data_len, ctx->mech.pParameter, key);
828
829 if (rc == CKR_OK) {
830 // the new init_v is the last decrypted data block
831 //
832 memcpy(ctx->mech.pParameter, cipher + (out_len - DES_BLOCK_SIZE),
833 DES_BLOCK_SIZE);
834
835 // copy the remaining 'new' input data to the temporary space
836 //
837 memcpy(context->data, in_data + (in_data_len - remain), remain);
838 context->len = remain;
839 }
840 free(cipher);
841 return rc;
842 }
843 }
844
845
846 //
847 //
des_ecb_encrypt_final(STDLL_TokData_t * tokdata,SESSION * sess,CK_BBOOL length_only,ENCR_DECR_CONTEXT * ctx,CK_BYTE * out_data,CK_ULONG * out_data_len)848 CK_RV des_ecb_encrypt_final(STDLL_TokData_t *tokdata,
849 SESSION *sess,
850 CK_BBOOL length_only,
851 ENCR_DECR_CONTEXT *ctx,
852 CK_BYTE *out_data, CK_ULONG *out_data_len)
853 {
854 DES_CONTEXT *context = NULL;
855
856 UNUSED(tokdata);
857 UNUSED(out_data);
858
859 if (!sess || !ctx || !out_data_len) {
860 TRACE_ERROR("%s received bad argument(s)\n", __func__);
861 return CKR_FUNCTION_FAILED;
862 }
863 // satisfy the compiler
864 //
865 if (length_only)
866 context = NULL;
867
868 context = (DES_CONTEXT *) ctx->context;
869
870 // DES-ECB does no padding so there had better not be
871 // any data in the context buffer. if there is it means
872 // that the overall data length was not a multiple of the blocksize
873 //
874 if (context->len != 0) {
875 TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
876 return CKR_DATA_LEN_RANGE;
877 }
878
879 *out_data_len = 0;
880
881 return CKR_OK;
882 }
883
884
885 //
886 //
des_ecb_decrypt_final(STDLL_TokData_t * tokdata,SESSION * sess,CK_BBOOL length_only,ENCR_DECR_CONTEXT * ctx,CK_BYTE * out_data,CK_ULONG * out_data_len)887 CK_RV des_ecb_decrypt_final(STDLL_TokData_t *tokdata,
888 SESSION *sess,
889 CK_BBOOL length_only,
890 ENCR_DECR_CONTEXT *ctx,
891 CK_BYTE *out_data, CK_ULONG *out_data_len)
892 {
893 DES_CONTEXT *context = NULL;
894
895 UNUSED(tokdata);
896 UNUSED(out_data);
897
898 if (!sess || !ctx || !out_data_len) {
899 TRACE_ERROR("%s received bad argument(s)\n", __func__);
900 return CKR_FUNCTION_FAILED;
901 }
902 // satisfy the compiler
903 //
904 if (length_only)
905 context = NULL;
906
907 context = (DES_CONTEXT *) ctx->context;
908
909 // DES-ECB does no padding so there had better not be
910 // any data in the context buffer. if there is it means
911 // that the overall data length was not a multiple of the blocksize
912 //
913 if (context->len != 0) {
914 TRACE_ERROR("%s\n", ock_err(ERR_ENCRYPTED_DATA_LEN_RANGE));
915 return CKR_ENCRYPTED_DATA_LEN_RANGE;
916 }
917
918 *out_data_len = 0;
919
920 return CKR_OK;
921 }
922
923
924 //
925 //
des_cbc_encrypt_final(STDLL_TokData_t * tokdata,SESSION * sess,CK_BBOOL length_only,ENCR_DECR_CONTEXT * ctx,CK_BYTE * out_data,CK_ULONG * out_data_len)926 CK_RV des_cbc_encrypt_final(STDLL_TokData_t *tokdata,
927 SESSION *sess,
928 CK_BBOOL length_only,
929 ENCR_DECR_CONTEXT *ctx,
930 CK_BYTE *out_data, CK_ULONG *out_data_len)
931 {
932 DES_CONTEXT *context = NULL;
933
934 UNUSED(tokdata);
935 UNUSED(out_data);
936
937 if (!sess || !ctx || !out_data_len) {
938 TRACE_ERROR("%s received bad argument(s)\n", __func__);
939 return CKR_FUNCTION_FAILED;
940 }
941 // satisfy the compiler
942 //
943 if (length_only)
944 context = NULL;
945
946 context = (DES_CONTEXT *) ctx->context;
947
948 // DES-CBC does no padding so there had better not be
949 // any data in the context buffer. if there is it means
950 // that the overall data length was not a multiple of the blocksize
951 //
952 if (context->len != 0) {
953 TRACE_ERROR("%s\n", ock_err(ERR_DATA_LEN_RANGE));
954 return CKR_DATA_LEN_RANGE;
955 }
956
957 *out_data_len = 0;
958
959 return CKR_OK;
960 }
961
962
963 //
964 //
des_cbc_decrypt_final(STDLL_TokData_t * tokdata,SESSION * sess,CK_BBOOL length_only,ENCR_DECR_CONTEXT * ctx,CK_BYTE * out_data,CK_ULONG * out_data_len)965 CK_RV des_cbc_decrypt_final(STDLL_TokData_t *tokdata,
966 SESSION *sess,
967 CK_BBOOL length_only,
968 ENCR_DECR_CONTEXT *ctx,
969 CK_BYTE *out_data, CK_ULONG *out_data_len)
970 {
971 DES_CONTEXT *context = NULL;
972
973 UNUSED(tokdata);
974 UNUSED(out_data);
975
976 if (!sess || !ctx || !out_data_len) {
977 TRACE_ERROR("%s received bad argument(s)\n", __func__);
978 return CKR_FUNCTION_FAILED;
979 }
980 // satisfy the compiler
981 //
982 if (length_only)
983 context = NULL;
984
985 context = (DES_CONTEXT *) ctx->context;
986
987 // DES-CBC does no padding so there had better not be
988 // any data in the context buffer. if there is it means
989 // that the overall data length was not a multiple of the blocksize
990 //
991 if (context->len != 0) {
992 TRACE_ERROR("%s\n", ock_err(ERR_ENCRYPTED_DATA_LEN_RANGE));
993 return CKR_ENCRYPTED_DATA_LEN_RANGE;
994 }
995
996 *out_data_len = 0;
997
998 return CKR_OK;
999 }
1000
1001
1002 //
1003 //
des_cbc_pad_encrypt_final(STDLL_TokData_t * tokdata,SESSION * sess,CK_BBOOL length_only,ENCR_DECR_CONTEXT * ctx,CK_BYTE * out_data,CK_ULONG * out_data_len)1004 CK_RV des_cbc_pad_encrypt_final(STDLL_TokData_t *tokdata,
1005 SESSION *sess,
1006 CK_BBOOL length_only,
1007 ENCR_DECR_CONTEXT *ctx,
1008 CK_BYTE *out_data, CK_ULONG *out_data_len)
1009 {
1010 DES_CONTEXT *context = NULL;
1011 OBJECT *key = NULL;
1012 CK_BYTE clear[2 * DES_BLOCK_SIZE];
1013 CK_ULONG out_len;
1014 CK_RV rc;
1015
1016
1017 if (!sess || !ctx || !out_data_len) {
1018 TRACE_ERROR("%s received bad argument(s)\n", __func__);
1019 return CKR_FUNCTION_FAILED;
1020 }
1021
1022 rc = object_mgr_find_in_map1(tokdata, ctx->key, &key);
1023 if (rc != CKR_OK) {
1024 TRACE_ERROR("Failed to find specified object.\n");
1025 return rc;
1026 }
1027
1028 context = (DES_CONTEXT *) ctx->context;
1029
1030 // there will never be more than one block in the context buffer
1031 // so the amount of output is as follows:
1032 // if less than 1 block stored, we generate one block of output
1033 // if a full block is stored, we generate two blocks of output (one pad
1034 // block)
1035 //
1036 if (context->len == DES_BLOCK_SIZE)
1037 out_len = 2 * DES_BLOCK_SIZE;
1038 else
1039 out_len = DES_BLOCK_SIZE;
1040
1041 if (length_only == TRUE) {
1042 *out_data_len = out_len;
1043 return CKR_OK;
1044 } else {
1045 memcpy(clear, context->data, context->len);
1046
1047 add_pkcs_padding(clear + context->len,
1048 DES_BLOCK_SIZE, context->len, out_len);
1049
1050 rc = ckm_des_cbc_encrypt(tokdata, clear, out_len, out_data,
1051 out_data_len, ctx->mech.pParameter, key);
1052 return rc;
1053 }
1054 }
1055
1056
1057 //
1058 //
des_cbc_pad_decrypt_final(STDLL_TokData_t * tokdata,SESSION * sess,CK_BBOOL length_only,ENCR_DECR_CONTEXT * ctx,CK_BYTE * out_data,CK_ULONG * out_data_len)1059 CK_RV des_cbc_pad_decrypt_final(STDLL_TokData_t *tokdata,
1060 SESSION *sess,
1061 CK_BBOOL length_only,
1062 ENCR_DECR_CONTEXT *ctx,
1063 CK_BYTE *out_data, CK_ULONG *out_data_len)
1064 {
1065 DES_CONTEXT *context = NULL;
1066 OBJECT *key = NULL;
1067 CK_BYTE clear[DES_BLOCK_SIZE];
1068 CK_BYTE cipher[DES_BLOCK_SIZE];
1069 CK_ULONG out_len;
1070 CK_RV rc;
1071
1072 if (!sess || !ctx || !out_data_len) {
1073 TRACE_ERROR("%s received bad argument(s)\n", __func__);
1074 return CKR_FUNCTION_FAILED;
1075 }
1076 rc = object_mgr_find_in_map1(tokdata, ctx->key, &key);
1077 if (rc != CKR_OK) {
1078 TRACE_ERROR("Failed to find specified object.\n");
1079 return rc;
1080 }
1081
1082 context = (DES_CONTEXT *) ctx->context;
1083
1084 // there had better be a full block in the context buffer
1085 //
1086 if (context->len != DES_BLOCK_SIZE) {
1087 TRACE_ERROR("%s\n", ock_err(ERR_ENCRYPTED_DATA_LEN_RANGE));
1088 return CKR_ENCRYPTED_DATA_LEN_RANGE;
1089 }
1090 // we don't know a priori how much data we'll be returning. we won't
1091 // know until after we decrypt it and strip the padding. it's possible
1092 // that we'll return nothing (the final block might be a padding block).
1093 //
1094 out_len = DES_BLOCK_SIZE; // upper bound on what we'll return
1095
1096 if (length_only == TRUE) {
1097 *out_data_len = out_len;
1098 return CKR_OK;
1099 } else {
1100 memcpy(cipher, context->data, DES_BLOCK_SIZE);
1101
1102 rc = ckm_des_cbc_decrypt(tokdata, cipher, DES_BLOCK_SIZE, clear,
1103 &out_len, ctx->mech.pParameter, key);
1104 if (rc == CKR_OK) {
1105 strip_pkcs_padding(clear, DES_BLOCK_SIZE, &out_len);
1106
1107 if (out_len != 0)
1108 memcpy(out_data, clear, out_len);
1109
1110 *out_data_len = out_len;
1111 }
1112
1113 return rc;
1114 }
1115 }
1116
1117
1118 //
1119 // mechanisms
1120 //
1121
1122
1123 //
1124 //
ckm_des_key_gen(STDLL_TokData_t * tokdata,TEMPLATE * tmpl)1125 CK_RV ckm_des_key_gen(STDLL_TokData_t *tokdata, TEMPLATE *tmpl)
1126 {
1127
1128 CK_ATTRIBUTE *value_attr = NULL;
1129 CK_ATTRIBUTE *opaque_attr = NULL;
1130 CK_ATTRIBUTE *key_type_attr = NULL;
1131 CK_ATTRIBUTE *class_attr = NULL;
1132 CK_ATTRIBUTE *local_attr = NULL;
1133 CK_BYTE *des_key = NULL;
1134 CK_BYTE dummy_key[DES_KEY_SIZE] = { 0, };
1135 CK_ULONG rc;
1136 CK_ULONG keysize;
1137
1138 if (token_specific.t_des_key_gen == NULL) {
1139 TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID));
1140 return CKR_MECHANISM_INVALID;
1141 }
1142
1143 if (is_secure_key_token())
1144 keysize = token_specific.token_keysize;
1145 else
1146 keysize = DES_KEY_SIZE;
1147
1148 if ((des_key = (CK_BYTE *) calloc(1, keysize)) == NULL) {
1149 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
1150 return CKR_HOST_MEMORY;
1151 }
1152
1153 rc = token_specific.t_des_key_gen(tokdata, des_key, keysize, DES_KEY_SIZE);
1154 if (rc != CKR_OK)
1155 goto err;
1156
1157 /* For secure-key keys put in CKA_IBM_OPAQUE
1158 * and put dummy_key in CKA_VALUE.
1159 */
1160 if (is_secure_key_token()) {
1161 opaque_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + keysize);
1162 if (!opaque_attr) {
1163 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
1164 rc = CKR_HOST_MEMORY;
1165 goto err;
1166 }
1167 opaque_attr->type = CKA_IBM_OPAQUE;
1168 opaque_attr->ulValueLen = keysize;
1169 opaque_attr->pValue = (CK_BYTE *) opaque_attr + sizeof(CK_ATTRIBUTE);
1170 memcpy(opaque_attr->pValue, des_key, keysize);
1171 template_update_attribute(tmpl, opaque_attr);
1172 }
1173
1174 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + DES_KEY_SIZE);
1175 key_type_attr =
1176 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
1177 class_attr =
1178 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS));
1179 local_attr =
1180 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
1181
1182 if (!value_attr || !key_type_attr || !class_attr || !local_attr) {
1183 if (value_attr)
1184 free(value_attr);
1185 if (key_type_attr)
1186 free(key_type_attr);
1187 if (class_attr)
1188 free(class_attr);
1189 if (local_attr)
1190 free(local_attr);
1191
1192 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
1193 rc = CKR_HOST_MEMORY;
1194 goto err;
1195 }
1196
1197 value_attr->type = CKA_VALUE;
1198 value_attr->ulValueLen = DES_KEY_SIZE;
1199 value_attr->pValue = (CK_BYTE *) value_attr + sizeof(CK_ATTRIBUTE);
1200 if (is_secure_key_token())
1201 memcpy(value_attr->pValue, dummy_key, DES_KEY_SIZE);
1202 else
1203 memcpy(value_attr->pValue, des_key, DES_KEY_SIZE);
1204 free(des_key);
1205
1206 key_type_attr->type = CKA_KEY_TYPE;
1207 key_type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
1208 key_type_attr->pValue = (CK_BYTE *) key_type_attr + sizeof(CK_ATTRIBUTE);
1209 *(CK_KEY_TYPE *) key_type_attr->pValue = CKK_DES;
1210
1211 class_attr->type = CKA_CLASS;
1212 class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS);
1213 class_attr->pValue = (CK_BYTE *) class_attr + sizeof(CK_ATTRIBUTE);
1214 *(CK_OBJECT_CLASS *) class_attr->pValue = CKO_SECRET_KEY;
1215
1216 local_attr->type = CKA_LOCAL;
1217 local_attr->ulValueLen = sizeof(CK_BBOOL);
1218 local_attr->pValue = (CK_BYTE *) local_attr + sizeof(CK_ATTRIBUTE);
1219 *(CK_BBOOL *) local_attr->pValue = TRUE;
1220
1221 template_update_attribute(tmpl, value_attr);
1222 template_update_attribute(tmpl, key_type_attr);
1223 template_update_attribute(tmpl, class_attr);
1224 template_update_attribute(tmpl, local_attr);
1225
1226 return CKR_OK;
1227
1228 err:
1229 if (des_key)
1230 free(des_key);
1231
1232 return rc;
1233 }
1234
1235 #if !(NOCDMF)
1236
1237 //
1238 //
ckm_cdmf_key_gen(STDLL_TokData_t * tokdata,TEMPLATE * tmpl)1239 CK_RV ckm_cdmf_key_gen(STDLL_TokData_t *tokdata, TEMPLATE *tmpl)
1240 {
1241 CK_ATTRIBUTE *value_attr = NULL;
1242 CK_ATTRIBUTE *key_type_attr = NULL;
1243 CK_ATTRIBUTE *class_attr = NULL;
1244 CK_ATTRIBUTE *local_attr = NULL;
1245 CK_BYTE cdmf_key[DES_KEY_SIZE];
1246 CK_ULONG repl_len, expected_repl_len;
1247 CK_ULONG rc;
1248
1249 repl_len = expected_repl_len = DES_KEY_SIZE;
1250
1251 rc = communicate(PK_CDMF_KEYGEN,
1252 NULL, 0, cdmf_key, &repl_len, NULL, 0, NULL, 0);
1253
1254 if (rc == CKR_OK) {
1255 if (repl_len != expected_repl_len)
1256 return CKR_GENERAL_ERROR;
1257 }
1258
1259 value_attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + DES_KEY_SIZE);
1260 key_type_attr =
1261 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE));
1262 class_attr =
1263 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_OBJECT_CLASS));
1264 local_attr =
1265 (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL));
1266
1267 if (!value_attr || !key_type_attr || !class_attr || !local_attr) {
1268 if (value_attr)
1269 free(value_attr);
1270 if (key_type_attr)
1271 free(key_type_attr);
1272 if (class_attr)
1273 free(class_attr);
1274 if (local_attr)
1275 free(local_attr);
1276
1277 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
1278 return CKR_HOST_MEMORY;
1279 }
1280
1281 value_attr->type = CKA_VALUE;
1282 value_attr->ulValueLen = DES_KEY_SIZE;
1283 value_attr->pValue = (CK_BYTE *) value_attr + sizeof(CK_ATTRIBUTE);
1284 memcpy(value_attr->pValue, cdmf_key, DES_KEY_SIZE);
1285
1286 key_type_attr->type = CKA_KEY_TYPE;
1287 key_type_attr->ulValueLen = sizeof(CK_KEY_TYPE);
1288 key_type_attr->pValue = (CK_BYTE *) key_type_attr + sizeof(CK_ATTRIBUTE);
1289 *(CK_KEY_TYPE *) key_type_attr->pValue = CKK_CDMF;
1290
1291 class_attr->type = CKA_CLASS;
1292 class_attr->ulValueLen = sizeof(CK_OBJECT_CLASS);
1293 class_attr->pValue = (CK_BYTE *) class_attr + sizeof(CK_ATTRIBUTE);
1294 *(CK_OBJECT_CLASS *) class_attr->pValue = CKO_SECRET_KEY;
1295
1296 local_attr->type = CKA_LOCAL;
1297 local_attr->ulValueLen = sizeof(CK_BBOOL);
1298 local_attr->pValue = (CK_BYTE *) local_attr + sizeof(CK_ATTRIBUTE);
1299 *(CK_BBOOL *) local_attr->pValue = TRUE;
1300
1301 template_update_attribute(tmpl, value_attr);
1302 template_update_attribute(tmpl, key_type_attr);
1303 template_update_attribute(tmpl, class_attr);
1304 template_update_attribute(tmpl, local_attr);
1305
1306 return CKR_OK;
1307 }
1308
1309 #endif
1310
1311 //
1312 //
ckm_des_ecb_encrypt(STDLL_TokData_t * tokdata,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key)1313 CK_RV ckm_des_ecb_encrypt(STDLL_TokData_t *tokdata,
1314 CK_BYTE *in_data,
1315 CK_ULONG in_data_len,
1316 CK_BYTE *out_data,
1317 CK_ULONG *out_data_len, OBJECT *key)
1318 {
1319 CK_ULONG rc;
1320
1321
1322 if (!in_data || !out_data || !key) {
1323 TRACE_ERROR("%s received bad argument(s)\n", __func__);
1324 return CKR_FUNCTION_FAILED;
1325 }
1326 if (*out_data_len < in_data_len) {
1327 TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
1328 return CKR_BUFFER_TOO_SMALL;
1329 }
1330
1331 if (token_specific.t_des_ecb == NULL) {
1332 TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID));
1333 return CKR_MECHANISM_INVALID;
1334 }
1335 rc = token_specific.t_des_ecb(tokdata, in_data, in_data_len,
1336 out_data, out_data_len, key, 1);
1337
1338 if (rc != CKR_OK)
1339 TRACE_DEVEL("Token specific des_ecb encrypt failed.\n");
1340
1341 return rc;
1342 }
1343
1344
1345 //
1346 //
ckm_des_ecb_decrypt(STDLL_TokData_t * tokdata,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key)1347 CK_RV ckm_des_ecb_decrypt(STDLL_TokData_t *tokdata,
1348 CK_BYTE *in_data,
1349 CK_ULONG in_data_len,
1350 CK_BYTE *out_data,
1351 CK_ULONG *out_data_len, OBJECT *key)
1352 {
1353 CK_ULONG rc;
1354
1355
1356
1357 if (!in_data || !out_data || !key) {
1358 TRACE_ERROR("%s received bad argument(s)\n", __func__);
1359 return CKR_FUNCTION_FAILED;
1360 }
1361 if (*out_data_len < in_data_len) {
1362 TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
1363 return CKR_BUFFER_TOO_SMALL;
1364 }
1365
1366 if (token_specific.t_des_ecb == NULL) {
1367 TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID));
1368 return CKR_MECHANISM_INVALID;
1369 }
1370 rc = token_specific.t_des_ecb(tokdata, in_data, in_data_len, out_data,
1371 out_data_len, key, 0);
1372 if (rc != CKR_OK)
1373 TRACE_ERROR("Token specific des ecb decrypt failed.\n");
1374
1375 return rc;
1376 }
1377
1378
1379 //
1380 //
ckm_des_cbc_encrypt(STDLL_TokData_t * tokdata,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,CK_BYTE * init_v,OBJECT * key)1381 CK_RV ckm_des_cbc_encrypt(STDLL_TokData_t *tokdata,
1382 CK_BYTE *in_data,
1383 CK_ULONG in_data_len,
1384 CK_BYTE *out_data,
1385 CK_ULONG *out_data_len,
1386 CK_BYTE *init_v, OBJECT *key)
1387 {
1388 CK_ULONG rc;
1389
1390
1391 if (!in_data || !out_data || !init_v || !key) {
1392 TRACE_ERROR("%s received bad argument(s)\n", __func__);
1393 return CKR_FUNCTION_FAILED;
1394 }
1395 if (*out_data_len < in_data_len) {
1396 *out_data_len = in_data_len;
1397 TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
1398 return CKR_BUFFER_TOO_SMALL;
1399 }
1400
1401 if (token_specific.t_des_cbc == NULL) {
1402 TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID));
1403 return CKR_MECHANISM_INVALID;
1404 }
1405 rc = token_specific.t_des_cbc(tokdata, in_data, in_data_len, out_data,
1406 out_data_len, key, init_v, 1);
1407
1408 if (rc != CKR_OK)
1409 TRACE_ERROR("Token specific dec cbc encrypt failed.\n");
1410
1411 return rc;
1412 }
1413
1414
1415 //
1416 //
ckm_des_cbc_decrypt(STDLL_TokData_t * tokdata,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,CK_BYTE * init_v,OBJECT * key)1417 CK_RV ckm_des_cbc_decrypt(STDLL_TokData_t *tokdata,
1418 CK_BYTE *in_data,
1419 CK_ULONG in_data_len,
1420 CK_BYTE *out_data,
1421 CK_ULONG *out_data_len,
1422 CK_BYTE *init_v, OBJECT *key)
1423 {
1424 CK_ULONG rc;
1425
1426
1427 if (!in_data || !out_data || !init_v || !key) {
1428 TRACE_ERROR("%s received bad argument(s)\n", __func__);
1429 return CKR_FUNCTION_FAILED;
1430 }
1431 if (*out_data_len < in_data_len) {
1432 TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
1433 return CKR_BUFFER_TOO_SMALL;
1434 }
1435
1436 if (token_specific.t_des_cbc == NULL) {
1437 TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID));
1438 return CKR_MECHANISM_INVALID;
1439 }
1440 rc = token_specific.t_des_cbc(tokdata, in_data, in_data_len, out_data,
1441 out_data_len, key, init_v, 0);
1442
1443 if (rc != CKR_OK)
1444 TRACE_ERROR("Token specific des cbc decrypt failed.\n");
1445
1446 return rc;
1447 }
1448
1449
1450 // we're preparing to wrap a key using DES. need to make sure the
1451 // data length is a integral multiple of the DES block size.
1452 //
1453 // PKCS #11 specifies that the padding shall be in the form of NULL
1454 // bytes appended to the data
1455 //
1456 // this routine works with either DES and 3DES as the wrapping mechanism
1457 //
ckm_des_wrap_format(STDLL_TokData_t * tokdata,CK_BBOOL length_only,CK_BYTE ** data,CK_ULONG * data_len)1458 CK_RV ckm_des_wrap_format(STDLL_TokData_t *tokdata,
1459 CK_BBOOL length_only,
1460 CK_BYTE **data, CK_ULONG *data_len)
1461 {
1462 CK_BYTE *ptr = NULL;
1463 CK_ULONG len1, len2;
1464
1465 UNUSED(tokdata);
1466
1467 len1 = *data_len;
1468 if (*data == NULL)
1469 len1 = 0;
1470
1471 // if the input key data isn't a multiple of the blocksize,
1472 // we pad with NULLs to the next blocksize multiple.
1473 //
1474 if (len1 % DES_BLOCK_SIZE != 0) {
1475 len2 = DES_BLOCK_SIZE * ((len1 / DES_BLOCK_SIZE) + 1);
1476
1477 if (length_only == FALSE) {
1478 /*
1479 * Don't use realloc here, since the buffer contains a key and the
1480 * old buffer needs to be cleansed before it is freed.
1481 */
1482 ptr = (CK_BYTE *)malloc(len2);
1483 if (!ptr) {
1484 TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
1485 return CKR_HOST_MEMORY;
1486 }
1487
1488 memset(ptr + len1, 0x0, (len2 - len1));
1489 if (*data != NULL) {
1490 memcpy(ptr, *data, len1);
1491 OPENSSL_cleanse(*data, len1);
1492 free(*data);
1493 }
1494
1495 *data = ptr;
1496 *data_len = len2;
1497 }
1498 }
1499
1500 return CKR_OK;
1501 }
1502