1 /*
2 * The Initial Developer of the Original Code is International
3 * Business Machines Corporation. Portions created by IBM
4 * Corporation are Copyright (C) 2005 International Business
5 * Machines Corporation. All Rights Reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the Common Public License as published by
9 * IBM Corporation; either version 1 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * Common Public License for more details.
16 *
17 * You should have received a copy of the Common Public License
18 * along with this program; if not, a copy can be viewed at
19 * http://www.opensource.org/licenses/cpl1.0.php.
20 */
21 /* (C) COPYRIGHT International Business Machines Corp. 2001, 2002, 2005 */
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include "tpmtok_int.h"
28
29 extern CK_RV
30 token_specific_rsa_verify_recover(
31 TSS_HCONTEXT hContext,
32 CK_BYTE *in_data,
33 CK_ULONG in_data_len,
34 CK_BYTE *out_data,
35 CK_ULONG *out_data_len,
36 OBJECT *key_obj);
37
38 CK_RV
ckm_rsa_key_pair_gen(TSS_HCONTEXT hContext,TEMPLATE * publ_tmpl,TEMPLATE * priv_tmpl)39 ckm_rsa_key_pair_gen(TSS_HCONTEXT hContext,
40 TEMPLATE * publ_tmpl,
41 TEMPLATE * priv_tmpl)
42 {
43 CK_RV rc;
44
45 rc = token_specific.t_rsa_generate_keypair(
46 hContext, publ_tmpl, priv_tmpl);
47
48 return (rc);
49 }
50
51 static CK_RV
ckm_rsa_encrypt(TSS_HCONTEXT hContext,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key_obj)52 ckm_rsa_encrypt(
53 TSS_HCONTEXT hContext,
54 CK_BYTE * in_data,
55 CK_ULONG in_data_len,
56 CK_BYTE * out_data,
57 CK_ULONG * out_data_len,
58 OBJECT * key_obj)
59 {
60 CK_ATTRIBUTE * attr = NULL;
61 CK_OBJECT_CLASS keyclass;
62 CK_RV rc;
63
64 rc = template_attribute_find(key_obj->template, CKA_CLASS, &attr);
65 if (rc == FALSE) {
66 return (CKR_FUNCTION_FAILED);
67 } else
68 keyclass = *(CK_OBJECT_CLASS *)attr->pValue;
69
70 if (keyclass != CKO_PUBLIC_KEY) {
71 return (CKR_FUNCTION_FAILED);
72 }
73
74 rc = token_specific.t_rsa_encrypt(hContext,
75 in_data, in_data_len,
76 out_data, out_data_len, key_obj);
77
78 return (rc);
79 }
80
81 static CK_RV
ckm_rsa_decrypt(TSS_HCONTEXT hContext,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key_obj)82 ckm_rsa_decrypt(
83 TSS_HCONTEXT hContext,
84 CK_BYTE * in_data,
85 CK_ULONG in_data_len,
86 CK_BYTE * out_data,
87 CK_ULONG * out_data_len,
88 OBJECT * key_obj) {
89 CK_ATTRIBUTE * attr = NULL;
90 CK_OBJECT_CLASS keyclass;
91 CK_RV rc;
92
93
94 rc = template_attribute_find(key_obj->template, CKA_CLASS, &attr);
95 if (rc == FALSE) {
96 return (CKR_FUNCTION_FAILED);
97 }
98 else
99 keyclass = *(CK_OBJECT_CLASS *)attr->pValue;
100
101 // this had better be a private key
102 //
103 if (keyclass != CKO_PRIVATE_KEY) {
104 return (CKR_FUNCTION_FAILED);
105 }
106 rc = token_specific.t_rsa_decrypt(hContext,
107 in_data, in_data_len,
108 out_data, out_data_len, key_obj);
109
110 return (rc);
111 }
112
113 static CK_RV
ckm_rsa_sign(TSS_HCONTEXT hContext,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len,OBJECT * key_obj)114 ckm_rsa_sign(
115 TSS_HCONTEXT hContext,
116 CK_BYTE * in_data,
117 CK_ULONG in_data_len,
118 CK_BYTE * out_data,
119 CK_ULONG * out_data_len,
120 OBJECT * key_obj) {
121 CK_ATTRIBUTE * attr = NULL;
122 CK_OBJECT_CLASS keyclass;
123 CK_RV rc;
124
125
126 rc = template_attribute_find(key_obj->template, CKA_CLASS, &attr);
127 if (rc == FALSE) {
128 return (CKR_FUNCTION_FAILED);
129 } else {
130 keyclass = *(CK_OBJECT_CLASS *)attr->pValue;
131 }
132
133 if (keyclass != CKO_PRIVATE_KEY) {
134 return (CKR_FUNCTION_FAILED);
135 }
136 rc = token_specific.t_rsa_sign(
137 hContext, in_data, in_data_len, out_data,
138 out_data_len, key_obj);
139
140 return (rc);
141 }
142
143 static CK_RV
ckm_rsa_verify(TSS_HCONTEXT hContext,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG out_data_len,OBJECT * key_obj)144 ckm_rsa_verify(
145 TSS_HCONTEXT hContext,
146 CK_BYTE * in_data,
147 CK_ULONG in_data_len,
148 CK_BYTE * out_data,
149 CK_ULONG out_data_len,
150 OBJECT * key_obj) {
151 CK_ATTRIBUTE * attr = NULL;
152 CK_OBJECT_CLASS keyclass;
153 CK_RV rc;
154
155
156 rc = template_attribute_find(key_obj->template, CKA_CLASS, &attr);
157 if (rc == FALSE) {
158 return (CKR_FUNCTION_FAILED);
159 }
160 else
161 keyclass = *(CK_OBJECT_CLASS *)attr->pValue;
162
163 if (keyclass != CKO_PUBLIC_KEY) {
164 return (CKR_FUNCTION_FAILED);
165 }
166 rc = token_specific.t_rsa_verify(hContext,
167 in_data, in_data_len, out_data,
168 out_data_len, key_obj);
169
170 return (rc);
171 }
172
173 /*ARGSUSED*/
174 CK_RV
rsa_pkcs_encrypt(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)175 rsa_pkcs_encrypt(SESSION *sess,
176 CK_BBOOL length_only,
177 ENCR_DECR_CONTEXT *ctx,
178 CK_BYTE *in_data,
179 CK_ULONG in_data_len,
180 CK_BYTE *out_data,
181 CK_ULONG *out_data_len)
182 {
183 OBJECT *key_obj = NULL;
184 CK_ATTRIBUTE *attr = NULL;
185 CK_ULONG modulus_bytes;
186 CK_BBOOL flag;
187 CK_RV rc;
188
189
190 rc = object_mgr_find_in_map1(sess->hContext, ctx->key, &key_obj);
191 if (rc != CKR_OK) {
192 return (rc);
193 }
194 flag = template_attribute_find(key_obj->template, CKA_MODULUS, &attr);
195 if (flag == FALSE) {
196 return (CKR_FUNCTION_FAILED);
197 } else {
198 modulus_bytes = attr->ulValueLen;
199 }
200
201 if (length_only == TRUE) {
202 *out_data_len = modulus_bytes;
203 return (CKR_OK);
204 }
205
206 if (*out_data_len < modulus_bytes) {
207 *out_data_len = modulus_bytes;
208 return (CKR_BUFFER_TOO_SMALL);
209 }
210
211 rc = ckm_rsa_encrypt(sess->hContext, in_data, in_data_len, out_data,
212 out_data_len, key_obj);
213 return (rc);
214 }
215
216 /*ARGSUSED*/
217 CK_RV
rsa_pkcs_decrypt(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)218 rsa_pkcs_decrypt(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,
224 CK_ULONG *out_data_len)
225 {
226 OBJECT *key_obj = NULL;
227 CK_ATTRIBUTE *attr = NULL;
228 CK_ULONG modulus_bytes;
229 CK_BBOOL flag;
230 CK_RV rc;
231
232
233 rc = object_mgr_find_in_map1(sess->hContext, ctx->key, &key_obj);
234 if (rc != CKR_OK) {
235 return (rc);
236 }
237 flag = template_attribute_find(key_obj->template, CKA_MODULUS, &attr);
238 if (flag == FALSE)
239 return (CKR_FUNCTION_FAILED);
240 else
241 modulus_bytes = attr->ulValueLen;
242
243 if (in_data_len != modulus_bytes) {
244 return (CKR_ENCRYPTED_DATA_LEN_RANGE);
245 }
246 if (length_only == TRUE) {
247 *out_data_len = modulus_bytes - 11;
248 return (CKR_OK);
249 }
250
251 rc = ckm_rsa_decrypt(sess->hContext, in_data,
252 modulus_bytes, out_data,
253 out_data_len, key_obj);
254
255 if (rc == CKR_DATA_LEN_RANGE) {
256 return (CKR_ENCRYPTED_DATA_LEN_RANGE);
257 }
258 return (rc);
259 }
260
261 CK_RV
rsa_pkcs_sign(SESSION * sess,CK_BBOOL length_only,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * out_data,CK_ULONG * out_data_len)262 rsa_pkcs_sign(SESSION *sess,
263 CK_BBOOL length_only,
264 SIGN_VERIFY_CONTEXT *ctx,
265 CK_BYTE *in_data,
266 CK_ULONG in_data_len,
267 CK_BYTE *out_data,
268 CK_ULONG *out_data_len)
269 {
270 OBJECT *key_obj = NULL;
271 CK_ATTRIBUTE *attr = NULL;
272 CK_ULONG modulus_bytes;
273 CK_BBOOL flag;
274 CK_RV rc;
275
276
277 if (! sess || ! ctx || ! out_data_len) {
278 return (CKR_FUNCTION_FAILED);
279 }
280 rc = object_mgr_find_in_map1(sess->hContext, ctx->key, &key_obj);
281 if (rc != CKR_OK) {
282 return (rc);
283 }
284 flag = template_attribute_find(key_obj->template, CKA_MODULUS, &attr);
285 if (flag == FALSE)
286 return (CKR_FUNCTION_FAILED);
287 else
288 modulus_bytes = attr->ulValueLen;
289
290 if (length_only == TRUE) {
291 *out_data_len = modulus_bytes;
292 return (CKR_OK);
293 }
294
295 if (*out_data_len < modulus_bytes) {
296 *out_data_len = modulus_bytes;
297 return (CKR_BUFFER_TOO_SMALL);
298 }
299
300 rc = ckm_rsa_sign(sess->hContext, in_data, in_data_len, out_data,
301 out_data_len, key_obj);
302 return (rc);
303 }
304
305 /*ARGSUSED*/
306 CK_RV
rsa_pkcs_verify(SESSION * sess,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * signature,CK_ULONG sig_len)307 rsa_pkcs_verify(SESSION * sess,
308 SIGN_VERIFY_CONTEXT * ctx,
309 CK_BYTE * in_data,
310 CK_ULONG in_data_len,
311 CK_BYTE * signature,
312 CK_ULONG sig_len)
313 {
314 OBJECT *key_obj = NULL;
315 CK_ATTRIBUTE *attr = NULL;
316 CK_ULONG modulus_bytes;
317 CK_BBOOL flag;
318 CK_RV rc;
319
320 rc = object_mgr_find_in_map1(sess->hContext, ctx->key, &key_obj);
321 if (rc != CKR_OK) {
322 return (rc);
323 }
324 flag = template_attribute_find(key_obj->template, CKA_MODULUS, &attr);
325 if (flag == FALSE) {
326 return (CKR_FUNCTION_FAILED);
327 }
328 else
329 modulus_bytes = attr->ulValueLen;
330
331 // check input data length restrictions
332 //
333 if (sig_len != modulus_bytes) {
334 return (CKR_SIGNATURE_LEN_RANGE);
335 }
336 // verify is a public key operation --> encrypt
337 //
338 rc = ckm_rsa_verify(sess->hContext, in_data, in_data_len, signature,
339 sig_len, key_obj);
340
341 return (rc);
342 }
343
344 CK_RV
rsa_pkcs_verify_recover(SESSION * sess,CK_BBOOL length_only,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * signature,CK_ULONG sig_len,CK_BYTE * out_data,CK_ULONG * out_data_len)345 rsa_pkcs_verify_recover(SESSION *sess,
346 CK_BBOOL length_only,
347 SIGN_VERIFY_CONTEXT *ctx,
348 CK_BYTE *signature,
349 CK_ULONG sig_len,
350 CK_BYTE *out_data,
351 CK_ULONG *out_data_len)
352 {
353 OBJECT *key_obj = NULL;
354 CK_ATTRIBUTE *attr = NULL;
355 CK_ULONG modulus_bytes;
356 CK_BBOOL flag;
357 CK_RV rc;
358
359 if (! sess || ! ctx || ! out_data_len) {
360 return (CKR_FUNCTION_FAILED);
361 }
362 rc = object_mgr_find_in_map1(sess->hContext, ctx->key, &key_obj);
363 if (rc != CKR_OK) {
364 return (rc);
365 }
366 flag = template_attribute_find(key_obj->template, CKA_MODULUS, &attr);
367 if (flag == FALSE) {
368 return (CKR_FUNCTION_FAILED);
369 }
370 else
371 modulus_bytes = attr->ulValueLen;
372
373 if (sig_len != modulus_bytes) {
374 return (CKR_SIGNATURE_LEN_RANGE);
375 }
376 if (length_only == TRUE) {
377 *out_data_len = modulus_bytes;
378 return (CKR_OK);
379 }
380
381 rc = token_specific_rsa_verify_recover(sess->hContext,
382 signature, modulus_bytes, out_data, out_data_len, key_obj);
383
384 return (rc);
385 }
386
387 CK_RV
rsa_hash_pkcs_sign(SESSION * sess,CK_BBOOL length_only,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * signature,CK_ULONG * sig_len)388 rsa_hash_pkcs_sign(SESSION * sess,
389 CK_BBOOL length_only,
390 SIGN_VERIFY_CONTEXT * ctx,
391 CK_BYTE * in_data,
392 CK_ULONG in_data_len,
393 CK_BYTE * signature,
394 CK_ULONG * sig_len)
395 {
396 CK_BYTE * ber_data = NULL;
397 CK_BYTE * octet_str = NULL;
398 CK_BYTE * oid = NULL;
399 CK_BYTE * tmp = NULL;
400
401 CK_ULONG buf1[16];
402
403 CK_BYTE hash[SHA1_DIGEST_LENGTH];
404 DIGEST_CONTEXT digest_ctx;
405 SIGN_VERIFY_CONTEXT sign_ctx;
406 CK_MECHANISM digest_mech;
407 CK_MECHANISM sign_mech;
408 CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len;
409 CK_RV rc;
410
411 if (! sess || ! ctx || ! in_data) {
412 return (CKR_FUNCTION_FAILED);
413 }
414 (void) memset(&digest_ctx, 0x0, sizeof (digest_ctx));
415 (void) memset(&sign_ctx, 0x0, sizeof (sign_ctx));
416
417 if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) {
418 digest_mech.mechanism = CKM_MD5;
419 oid = ber_AlgMd5;
420 oid_len = ber_AlgMd5Len;
421 hash_len = MD5_DIGEST_LENGTH;
422 } else {
423 digest_mech.mechanism = CKM_SHA_1;
424 oid = ber_AlgSha1;
425 oid_len = ber_AlgSha1Len;
426 hash_len = SHA1_DIGEST_LENGTH;
427 }
428
429 digest_mech.ulParameterLen = 0;
430 digest_mech.pParameter = NULL;
431
432 rc = digest_mgr_init(sess, &digest_ctx, &digest_mech);
433 if (rc != CKR_OK) {
434 goto error;
435 }
436 rc = digest_mgr_digest(sess, length_only, &digest_ctx, in_data,
437 in_data_len, hash, &hash_len);
438 if (rc != CKR_OK)
439 goto error;
440
441 rc = ber_encode_OCTET_STRING(FALSE, &octet_str, &octet_str_len,
442 hash, hash_len);
443 if (rc != CKR_OK) {
444 goto error;
445 }
446 tmp = (CK_BYTE *)buf1;
447 (void) memcpy(tmp, oid, oid_len);
448 (void) memcpy(tmp + oid_len, octet_str, octet_str_len);
449
450 rc = ber_encode_SEQUENCE(FALSE, &ber_data, &ber_data_len,
451 tmp, (oid_len + octet_str_len));
452 if (rc != CKR_OK)
453 goto error;
454
455 sign_mech.mechanism = CKM_RSA_PKCS;
456 sign_mech.ulParameterLen = 0;
457 sign_mech.pParameter = NULL;
458
459 rc = sign_mgr_init(sess, &sign_ctx, &sign_mech, FALSE, ctx->key);
460 if (rc != CKR_OK)
461 goto error;
462
463 rc = sign_mgr_sign(sess, length_only, &sign_ctx, ber_data,
464 ber_data_len, signature, sig_len);
465
466 error:
467 if (octet_str) free(octet_str);
468 if (ber_data) free(ber_data);
469 (void) digest_mgr_cleanup(&digest_ctx);
470 (void) sign_mgr_cleanup(&sign_ctx);
471 return (rc);
472 }
473
474 CK_RV
rsa_hash_pkcs_sign_update(SESSION * sess,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len)475 rsa_hash_pkcs_sign_update(
476 SESSION * sess,
477 SIGN_VERIFY_CONTEXT * ctx,
478 CK_BYTE * in_data,
479 CK_ULONG in_data_len)
480 {
481 RSA_DIGEST_CONTEXT * context = NULL;
482 CK_MECHANISM digest_mech;
483 CK_RV rc;
484
485 if (! sess || ! ctx || ! in_data)
486 return (CKR_FUNCTION_FAILED);
487
488 context = (RSA_DIGEST_CONTEXT *)ctx->context;
489
490 if (context->flag == FALSE) {
491 if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS)
492 digest_mech.mechanism = CKM_MD5;
493 else
494 digest_mech.mechanism = CKM_SHA_1;
495
496 digest_mech.ulParameterLen = 0;
497 digest_mech.pParameter = NULL;
498
499 rc = digest_mgr_init(sess, &context->hash_context,
500 &digest_mech);
501 if (rc != CKR_OK) {
502 goto error;
503 }
504 context->flag = TRUE;
505 }
506
507 rc = digest_mgr_digest_update(sess, &context->hash_context,
508 in_data, in_data_len);
509 if (rc != CKR_OK) {
510 goto error;
511 }
512 return (CKR_OK);
513 error:
514 (void) digest_mgr_cleanup(&context->hash_context);
515 return (rc);
516 }
517
518 CK_RV
rsa_hash_pkcs_verify(SESSION * sess,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len,CK_BYTE * signature,CK_ULONG sig_len)519 rsa_hash_pkcs_verify(SESSION * sess,
520 SIGN_VERIFY_CONTEXT * ctx,
521 CK_BYTE * in_data,
522 CK_ULONG in_data_len,
523 CK_BYTE * signature,
524 CK_ULONG sig_len)
525 {
526 CK_BYTE * ber_data = NULL;
527 CK_BYTE * octet_str = NULL;
528 CK_BYTE * oid = NULL;
529 CK_BYTE * tmp = NULL;
530
531 CK_ULONG buf1[16];
532 CK_BYTE hash[SHA1_DIGEST_LENGTH];
533 DIGEST_CONTEXT digest_ctx;
534 SIGN_VERIFY_CONTEXT verify_ctx;
535 CK_MECHANISM digest_mech;
536 CK_MECHANISM verify_mech;
537 CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len;
538 CK_RV rc;
539
540 if (! sess || ! ctx || ! in_data) {
541 return (CKR_FUNCTION_FAILED);
542 }
543 (void) memset(&digest_ctx, 0x0, sizeof (digest_ctx));
544 (void) memset(&verify_ctx, 0x0, sizeof (verify_ctx));
545
546 if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) {
547 digest_mech.mechanism = CKM_MD5;
548 oid = ber_AlgMd5;
549 oid_len = ber_AlgMd5Len;
550 hash_len = MD5_DIGEST_LENGTH;
551 } else {
552 digest_mech.mechanism = CKM_SHA_1;
553 oid = ber_AlgSha1;
554 oid_len = ber_AlgSha1Len;
555 hash_len = SHA1_DIGEST_LENGTH;
556 }
557
558 digest_mech.ulParameterLen = 0;
559 digest_mech.pParameter = NULL;
560
561 rc = digest_mgr_init(sess, &digest_ctx, &digest_mech);
562 if (rc != CKR_OK) {
563 goto done;
564 }
565 rc = digest_mgr_digest(sess, FALSE, &digest_ctx, in_data,
566 in_data_len, hash, &hash_len);
567 if (rc != CKR_OK) {
568 goto done;
569 }
570 rc = ber_encode_OCTET_STRING(FALSE, &octet_str, &octet_str_len,
571 hash, hash_len);
572 if (rc != CKR_OK)
573 goto done;
574 tmp = (CK_BYTE *)buf1;
575 (void) memcpy(tmp, oid, oid_len);
576 (void) memcpy(tmp + oid_len, octet_str, octet_str_len);
577
578 rc = ber_encode_SEQUENCE(FALSE, &ber_data, &ber_data_len, tmp,
579 (oid_len + octet_str_len));
580 if (rc != CKR_OK) {
581 goto done;
582 }
583
584 verify_mech.mechanism = CKM_RSA_PKCS;
585 verify_mech.ulParameterLen = 0;
586 verify_mech.pParameter = NULL;
587
588 rc = verify_mgr_init(sess, &verify_ctx, &verify_mech, FALSE, ctx->key);
589 if (rc != CKR_OK) {
590 goto done;
591 }
592 rc = verify_mgr_verify(sess, &verify_ctx, ber_data,
593 ber_data_len, signature, sig_len);
594 done:
595 if (octet_str) free(octet_str);
596 if (ber_data) free(ber_data);
597
598 (void) digest_mgr_cleanup(&digest_ctx);
599 (void) sign_mgr_cleanup(&verify_ctx);
600 return (rc);
601 }
602
603 CK_RV
rsa_hash_pkcs_verify_update(SESSION * sess,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * in_data,CK_ULONG in_data_len)604 rsa_hash_pkcs_verify_update(SESSION * sess,
605 SIGN_VERIFY_CONTEXT * ctx,
606 CK_BYTE *in_data,
607 CK_ULONG in_data_len)
608 {
609 RSA_DIGEST_CONTEXT * context = NULL;
610 CK_MECHANISM digest_mech;
611 CK_RV rc;
612
613 if (! sess || ! ctx || ! in_data) {
614 return (CKR_FUNCTION_FAILED);
615 }
616 context = (RSA_DIGEST_CONTEXT *)ctx->context;
617
618 if (context->flag == FALSE) {
619 if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS)
620 digest_mech.mechanism = CKM_MD5;
621 else
622 digest_mech.mechanism = CKM_SHA_1;
623
624 digest_mech.ulParameterLen = 0;
625 digest_mech.pParameter = NULL;
626
627 rc = digest_mgr_init(sess, &context->hash_context,
628 &digest_mech);
629 if (rc != CKR_OK)
630 goto error;
631 context->flag = TRUE;
632 }
633
634 rc = digest_mgr_digest_update(sess, &context->hash_context,
635 in_data, in_data_len);
636 if (rc != CKR_OK)
637 goto error;
638 return (CKR_OK);
639 error:
640 (void) digest_mgr_cleanup(&context->hash_context);
641 return (rc);
642 }
643
644 CK_RV
rsa_hash_pkcs_sign_final(SESSION * sess,CK_BBOOL length_only,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * signature,CK_ULONG * sig_len)645 rsa_hash_pkcs_sign_final(SESSION * sess,
646 CK_BBOOL length_only,
647 SIGN_VERIFY_CONTEXT * ctx,
648 CK_BYTE * signature,
649 CK_ULONG * sig_len)
650 {
651 CK_BYTE * ber_data = NULL;
652 CK_BYTE * octet_str = NULL;
653 CK_BYTE * oid = NULL;
654 CK_BYTE * tmp = NULL;
655
656 CK_ULONG buf1[16];
657 CK_BYTE hash[SHA1_DIGEST_LENGTH];
658 RSA_DIGEST_CONTEXT * context = NULL;
659 CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len;
660 CK_MECHANISM sign_mech;
661 SIGN_VERIFY_CONTEXT sign_ctx;
662 CK_RV rc;
663
664 if (! sess || ! ctx || ! sig_len) {
665 return (CKR_FUNCTION_FAILED);
666 }
667
668 if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) {
669 oid = ber_AlgMd5;
670 oid_len = ber_AlgMd5Len;
671 hash_len = MD5_DIGEST_LENGTH;
672 } else {
673 oid = ber_AlgSha1;
674 oid_len = ber_AlgSha1Len;
675 hash_len = SHA1_DIGEST_LENGTH;
676 }
677
678 (void) memset(&sign_ctx, 0x0, sizeof (sign_ctx));
679
680 context = (RSA_DIGEST_CONTEXT *)ctx->context;
681
682 rc = digest_mgr_digest_final(sess,
683 &context->hash_context, hash, &hash_len);
684 if (rc != CKR_OK) {
685 goto done;
686 }
687
688 rc = ber_encode_OCTET_STRING(FALSE, &octet_str, &octet_str_len,
689 hash, hash_len);
690 if (rc != CKR_OK) {
691 goto done;
692 }
693 tmp = (CK_BYTE *)buf1;
694 (void) memcpy(tmp, oid, oid_len);
695 (void) memcpy(tmp + oid_len, octet_str, octet_str_len);
696
697 rc = ber_encode_SEQUENCE(FALSE, &ber_data, &ber_data_len,
698 tmp, (oid_len + octet_str_len));
699 if (rc != CKR_OK) {
700 goto done;
701 }
702 sign_mech.mechanism = CKM_RSA_PKCS;
703 sign_mech.ulParameterLen = 0;
704 sign_mech.pParameter = NULL;
705
706 rc = sign_mgr_init(sess, &sign_ctx, &sign_mech, FALSE, ctx->key);
707 if (rc != CKR_OK) {
708 goto done;
709 }
710 rc = sign_mgr_sign(sess, length_only, &sign_ctx, ber_data,
711 ber_data_len, signature, sig_len);
712
713 if (length_only == TRUE || rc == CKR_BUFFER_TOO_SMALL) {
714 (void) sign_mgr_cleanup(&sign_ctx);
715 return (rc);
716 }
717
718 done:
719 if (octet_str) free(octet_str);
720 if (ber_data) free(ber_data);
721
722 (void) digest_mgr_cleanup(&context->hash_context);
723 (void) sign_mgr_cleanup(&sign_ctx);
724 return (rc);
725 }
726
727 CK_RV
rsa_hash_pkcs_verify_final(SESSION * sess,SIGN_VERIFY_CONTEXT * ctx,CK_BYTE * signature,CK_ULONG sig_len)728 rsa_hash_pkcs_verify_final(SESSION * sess,
729 SIGN_VERIFY_CONTEXT * ctx,
730 CK_BYTE * signature,
731 CK_ULONG sig_len)
732 {
733 CK_BYTE * ber_data = NULL;
734 CK_BYTE * octet_str = NULL;
735 CK_BYTE * oid = NULL;
736 CK_BYTE * tmp = NULL;
737
738 CK_ULONG buf1[16];
739 CK_BYTE hash[SHA1_DIGEST_LENGTH];
740 RSA_DIGEST_CONTEXT * context = NULL;
741 CK_ULONG ber_data_len, hash_len, octet_str_len, oid_len;
742 CK_MECHANISM verify_mech;
743 SIGN_VERIFY_CONTEXT verify_ctx;
744 CK_RV rc;
745
746 if (! sess || ! ctx || ! signature) {
747 return (CKR_FUNCTION_FAILED);
748 }
749 if (ctx->mech.mechanism == CKM_MD5_RSA_PKCS) {
750 oid = ber_AlgMd5;
751 oid_len = ber_AlgMd5Len;
752 hash_len = MD5_DIGEST_LENGTH;
753 } else {
754 oid = ber_AlgSha1;
755 oid_len = ber_AlgSha1Len;
756 hash_len = SHA1_DIGEST_LENGTH;
757 }
758
759 (void) memset(&verify_ctx, 0x0, sizeof (verify_ctx));
760
761 context = (RSA_DIGEST_CONTEXT *)ctx->context;
762
763 rc = digest_mgr_digest_final(sess, &context->hash_context,
764 hash, &hash_len);
765 if (rc != CKR_OK) {
766 goto done;
767 }
768 rc = ber_encode_OCTET_STRING(FALSE, &octet_str, &octet_str_len,
769 hash, hash_len);
770 if (rc != CKR_OK) {
771 goto done;
772 }
773 tmp = (CK_BYTE *)buf1;
774 (void) memcpy(tmp, oid, oid_len);
775 (void) memcpy(tmp + oid_len, octet_str, octet_str_len);
776
777 rc = ber_encode_SEQUENCE(FALSE, &ber_data, &ber_data_len,
778 tmp, (oid_len + octet_str_len));
779 if (rc != CKR_OK) {
780 goto done;
781 }
782 verify_mech.mechanism = CKM_RSA_PKCS;
783 verify_mech.ulParameterLen = 0;
784 verify_mech.pParameter = NULL;
785
786 rc = verify_mgr_init(sess, &verify_ctx, &verify_mech, FALSE, ctx->key);
787 if (rc != CKR_OK) {
788 goto done;
789 }
790 rc = verify_mgr_verify(sess, &verify_ctx, ber_data,
791 ber_data_len, signature, sig_len);
792 done:
793 if (octet_str) free(octet_str);
794 if (ber_data) free(ber_data);
795 (void) digest_mgr_cleanup(&context->hash_context);
796 (void) verify_mgr_cleanup(&verify_ctx);
797 return (rc);
798 }
799