]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/CyaSSL/mcapi/crypto.c
Update CyaSSL to latest version.
[freertos] / FreeRTOS-Plus / Source / CyaSSL / mcapi / crypto.c
1 /* crypto.c
2  *
3  * Copyright (C) 2006-2014 wolfSSL Inc.
4  *
5  * This file is part of CyaSSL.
6  *
7  * CyaSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * CyaSSL 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  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22
23 /* Implements Microchip CRYPTO API layer */
24
25
26
27 #include "crypto.h"
28
29 #include <cyassl/ctaocrypt/settings.h>
30
31 #include <cyassl/ctaocrypt/md5.h>
32 #include <cyassl/ctaocrypt/sha.h>
33 #include <cyassl/ctaocrypt/sha256.h>
34 #include <cyassl/ctaocrypt/sha512.h>
35 #include <cyassl/ctaocrypt/hmac.h>
36 #include <cyassl/ctaocrypt/compress.h>
37 #include <cyassl/ctaocrypt/random.h>
38 #include <cyassl/ctaocrypt/des3.h>
39 #include <cyassl/ctaocrypt/aes.h>
40 #include <cyassl/ctaocrypt/rsa.h>
41 #include <cyassl/ctaocrypt/ecc.h>
42 #include <cyassl/ctaocrypt/error-crypt.h>
43
44
45 /* Initialize MD5 */
46 int CRYPT_MD5_Initialize(CRYPT_MD5_CTX* md5)
47 {
48     typedef char md5_test[sizeof(CRYPT_MD5_CTX) >= sizeof(Md5) ? 1 : -1];
49     (void)sizeof(md5_test);
50
51     if (md5 == NULL)
52         return BAD_FUNC_ARG;
53
54     InitMd5((Md5*)md5);
55
56     return 0;
57 }
58
59
60 /* Add data to MD5 */
61 int CRYPT_MD5_DataAdd(CRYPT_MD5_CTX* md5, const unsigned char* input,
62                       unsigned int sz)
63 {
64     if (md5 == NULL || input == NULL)
65         return BAD_FUNC_ARG;
66
67     Md5Update((Md5*)md5, input, sz);
68
69     return 0;
70 }
71
72
73 /* Get MD5 Final into digest */
74 int CRYPT_MD5_Finalize(CRYPT_MD5_CTX* md5, unsigned char* digest)
75 {
76     if (md5 == NULL || digest == NULL)
77         return BAD_FUNC_ARG;
78
79     Md5Final((Md5*)md5, digest);
80
81     return 0;
82 }
83
84
85 /* Initialize SHA */
86 int CRYPT_SHA_Initialize(CRYPT_SHA_CTX* sha)
87 {
88     typedef char sha_test[sizeof(CRYPT_SHA_CTX) >= sizeof(Sha) ? 1 : -1];
89     (void)sizeof(sha_test);
90
91     if (sha == NULL)
92         return BAD_FUNC_ARG;
93
94     return InitSha((Sha*)sha);
95 }
96
97
98 /* Add data to SHA */
99 int CRYPT_SHA_DataAdd(CRYPT_SHA_CTX* sha, const unsigned char* input,
100                        unsigned int sz)
101 {
102     if (sha == NULL || input == NULL)
103         return BAD_FUNC_ARG;
104
105     return ShaUpdate((Sha*)sha, input, sz);
106 }
107
108
109 /* Get SHA Final into digest */
110 int CRYPT_SHA_Finalize(CRYPT_SHA_CTX* sha, unsigned char* digest)
111 {
112     if (sha == NULL || digest == NULL)
113         return BAD_FUNC_ARG;
114
115     return ShaFinal((Sha*)sha, digest);
116 }
117
118
119 /* Initialize SHA-256 */
120 int CRYPT_SHA256_Initialize(CRYPT_SHA256_CTX* sha256)
121 {
122     typedef char sha_test[sizeof(CRYPT_SHA256_CTX) >= sizeof(Sha256) ? 1 : -1];
123     (void)sizeof(sha_test);
124
125     if (sha256 == NULL)
126         return BAD_FUNC_ARG;
127
128     return InitSha256((Sha256*)sha256);
129 }
130
131
132 /* Add data to SHA-256 */
133 int CRYPT_SHA256_DataAdd(CRYPT_SHA256_CTX* sha256, const unsigned char* input,
134                          unsigned int sz)
135 {
136     if (sha256 == NULL || input == NULL)
137         return BAD_FUNC_ARG;
138
139     return Sha256Update((Sha256*)sha256, input, sz);
140 }
141
142
143 /* Get SHA-256 Final into digest */
144 int CRYPT_SHA256_Finalize(CRYPT_SHA256_CTX* sha256, unsigned char* digest)
145 {
146     if (sha256 == NULL || digest == NULL)
147         return BAD_FUNC_ARG;
148
149     return Sha256Final((Sha256*)sha256, digest);
150 }
151
152
153 /* Initialize SHA-384 */
154 int CRYPT_SHA384_Initialize(CRYPT_SHA384_CTX* sha384)
155 {
156     typedef char sha_test[sizeof(CRYPT_SHA384_CTX) >= sizeof(Sha384) ? 1 : -1];
157     (void)sizeof(sha_test);
158
159     if (sha384 == NULL)
160         return BAD_FUNC_ARG;
161
162     return InitSha384((Sha384*)sha384);
163 }
164
165
166 /* Add data to SHA-384 */
167 int CRYPT_SHA384_DataAdd(CRYPT_SHA384_CTX* sha384, const unsigned char* input,
168                          unsigned int sz)
169 {
170     if (sha384 == NULL || input == NULL)
171         return BAD_FUNC_ARG;
172
173     return Sha384Update((Sha384*)sha384, input, sz);
174 }
175
176
177 /* Get SHA-384 Final into digest */
178 int CRYPT_SHA384_Finalize(CRYPT_SHA384_CTX* sha384, unsigned char* digest)
179 {
180     if (sha384 == NULL || digest == NULL)
181         return BAD_FUNC_ARG;
182
183     return Sha384Final((Sha384*)sha384, digest);
184 }
185
186
187 /* Initialize SHA-512 */
188 int CRYPT_SHA512_Initialize(CRYPT_SHA512_CTX* sha512)
189 {
190     typedef char sha_test[sizeof(CRYPT_SHA512_CTX) >= sizeof(Sha512) ? 1 : -1];
191     (void)sizeof(sha_test);
192
193     if (sha512 == NULL)
194         return BAD_FUNC_ARG;
195
196     return InitSha512((Sha512*)sha512);
197 }
198
199
200 /* Add data to SHA-512 */
201 int CRYPT_SHA512_DataAdd(CRYPT_SHA512_CTX* sha512, const unsigned char* input,
202                          unsigned int sz)
203 {
204     if (sha512 == NULL || input == NULL)
205         return BAD_FUNC_ARG;
206
207     return Sha512Update((Sha512*)sha512, input, sz);
208 }
209
210
211 /* Get SHA-512 Final into digest */
212 int CRYPT_SHA512_Finalize(CRYPT_SHA512_CTX* sha512, unsigned char* digest)
213 {
214     if (sha512 == NULL || digest == NULL)
215         return BAD_FUNC_ARG;
216
217     return Sha512Final((Sha512*)sha512, digest);
218 }
219
220
221 /* Set HMAC key with type */
222 int CRYPT_HMAC_SetKey(CRYPT_HMAC_CTX* hmac, int type, const unsigned char* key,
223                       unsigned int sz)
224 {
225     typedef char hmac_test[sizeof(CRYPT_HMAC_CTX) >= sizeof(Hmac) ? 1 : -1];
226     (void)sizeof(hmac_test);
227
228     if (hmac == NULL || key == NULL)
229         return BAD_FUNC_ARG;
230
231     if (type != CRYPT_HMAC_SHA && type != CRYPT_HMAC_SHA256 &&
232         type != CRYPT_HMAC_SHA384 && type != CRYPT_HMAC_SHA512) {
233         return BAD_FUNC_ARG;  /* bad hmac type */
234     }
235
236     return HmacSetKey((Hmac*)hmac, type, key, sz);
237 }
238
239
240 int CRYPT_HMAC_DataAdd(CRYPT_HMAC_CTX* hmac, const unsigned char* input,
241                        unsigned int sz)
242 {
243     if (hmac == NULL || input == NULL)
244         return BAD_FUNC_ARG;
245
246     return HmacUpdate((Hmac*)hmac, input, sz);
247 }
248
249
250 /* Get HMAC Final into digest */
251 int CRYPT_HMAC_Finalize(CRYPT_HMAC_CTX* hmac, unsigned char* digest)
252 {
253     if (hmac == NULL || digest == NULL)
254         return BAD_FUNC_ARG;
255
256     return HmacFinal((Hmac*)hmac, digest);
257 }
258
259
260 /* Huffman Compression, set flag to do static, otherwise dynamic */
261 /* return compressed size, otherwise < 0 for error */
262 int CRYPT_HUFFMAN_Compress(unsigned char* out, unsigned int outSz,
263                            const unsigned char* in, unsigned int inSz,
264                            unsigned int flags)
265 {
266     if (out == NULL || in == NULL)
267         return BAD_FUNC_ARG;
268
269     return Compress(out, outSz, in, inSz, flags);
270 }
271
272
273 /* Huffman DeCompression, self determines type */
274 /* return decompressed size, otherwise < 0 for error */
275 int CRYPT_HUFFMAN_DeCompress(unsigned char* out, unsigned int outSz,
276                              const unsigned char* in, unsigned int inSz)
277 {
278     if (out == NULL || in == NULL)
279         return BAD_FUNC_ARG;
280
281     return DeCompress(out, outSz, in, inSz);
282 }
283
284
285 /* RNG Initialize, < 0 on error */
286 int CRYPT_RNG_Initialize(CRYPT_RNG_CTX* rng)
287 {
288     typedef char rng_test[sizeof(CRYPT_RNG_CTX) >= sizeof(RNG) ? 1 : -1];
289     (void)sizeof(rng_test);
290
291     if (rng == NULL)
292         return BAD_FUNC_ARG;
293
294     return InitRng((RNG*)rng);
295 }
296
297
298 /* RNG Get single bytes, < 0 on error */
299 int CRYPT_RNG_Get(CRYPT_RNG_CTX* rng, unsigned char* b)
300 {
301     if (rng == NULL || b == NULL)
302         return BAD_FUNC_ARG;
303
304     return RNG_GenerateByte((RNG*)rng, (byte*)b);
305 }
306
307
308 /* RNG Block Generation of sz bytes, < 0 on error */
309 int CRYPT_RNG_BlockGenerate(CRYPT_RNG_CTX* rng, unsigned char* b,
310                             unsigned int sz)
311 {
312     if (rng == NULL || b == NULL)
313         return BAD_FUNC_ARG;
314
315     return RNG_GenerateBlock((RNG*)rng, b, sz);
316 }
317
318
319 /* Triple DES Key Set, may have iv, will have direction */
320 int CRYPT_TDES_KeySet(CRYPT_TDES_CTX* tdes, const unsigned char* key,
321                       const unsigned char* iv, int dir)
322 {
323     typedef char tdes_test[sizeof(CRYPT_TDES_CTX) >= sizeof(Des3) ? 1 : -1];
324     (void)sizeof(tdes_test);
325
326     if (tdes == NULL || key == NULL)
327         return BAD_FUNC_ARG;
328
329     return Des3_SetKey((Des3*)tdes, key, iv, dir);
330 }
331
332
333 /* Triple DES Iv Set, sometimes added later */
334 int CRYPT_TDES_IvSet(CRYPT_TDES_CTX* tdes, const unsigned char* iv)
335 {
336     if (tdes == NULL || iv == NULL)
337         return BAD_FUNC_ARG;
338
339     return Des3_SetIV((Des3*)tdes, iv);
340 }
341
342
343 /* Triple DES CBC Encrypt */
344 int CRYPT_TDES_CBC_Encrypt(CRYPT_TDES_CTX* tdes, unsigned char* out,
345                            const unsigned char* in, unsigned int inSz)
346 {
347     if (tdes == NULL || out == NULL || in == NULL)
348         return BAD_FUNC_ARG;
349
350     return Des3_CbcEncrypt((Des3*)tdes, out, in, inSz);
351 }
352
353
354 /* Triple DES CBC Decrypt */
355 int CRYPT_TDES_CBC_Decrypt(CRYPT_TDES_CTX* tdes, unsigned char* out,
356                            const unsigned char* in, unsigned int inSz)
357 {
358     if (tdes == NULL || out == NULL || in == NULL)
359         return BAD_FUNC_ARG;
360
361     return Des3_CbcDecrypt((Des3*)tdes, out, in, inSz);
362 }
363
364
365 /* AES Key Set, may have iv, will have direction */
366 int CRYPT_AES_KeySet(CRYPT_AES_CTX* aes, const unsigned char* key,
367                      unsigned int keyLen, const unsigned char* iv, int dir)
368 {
369     typedef char aes_test[sizeof(CRYPT_AES_CTX) >= sizeof(Aes) ? 1 : -1];
370     (void)sizeof(aes_test);
371
372     if (aes == NULL || key == NULL)
373         return BAD_FUNC_ARG;
374
375     return AesSetKey((Aes*)aes, key, keyLen, iv, dir);
376 }
377
378
379 /* AES Iv Set, sometimes added later */
380 int CRYPT_AES_IvSet(CRYPT_AES_CTX* aes, const unsigned char* iv)
381 {
382     if (aes == NULL || iv == NULL)
383         return BAD_FUNC_ARG;
384
385     return AesSetIV((Aes*)aes, iv);
386 }
387
388
389 /* AES CBC Encrypt */
390 int CRYPT_AES_CBC_Encrypt(CRYPT_AES_CTX* aes, unsigned char* out,
391                           const unsigned char* in, unsigned int inSz)
392 {
393     if (aes == NULL || out == NULL || in == NULL)
394         return BAD_FUNC_ARG;
395
396     return AesCbcEncrypt((Aes*)aes, out, in, inSz);
397 }
398
399
400 /* AES CBC Decrypt */
401 int CRYPT_AES_CBC_Decrypt(CRYPT_AES_CTX* aes, unsigned char* out,
402                           const unsigned char* in, unsigned int inSz)
403 {
404     if (aes == NULL || out == NULL || in == NULL)
405         return BAD_FUNC_ARG;
406
407     return AesCbcDecrypt((Aes*)aes, out, in, inSz);
408 }
409
410
411 /* AES CTR Encrypt (used for decrypt too, with ENCRYPT key setup) */
412 int CRYPT_AES_CTR_Encrypt(CRYPT_AES_CTX* aes, unsigned char* out,
413                           const unsigned char* in, unsigned int inSz)
414 {
415     if (aes == NULL || out == NULL || in == NULL)
416         return BAD_FUNC_ARG;
417
418     AesCtrEncrypt((Aes*)aes, out, in, inSz);
419
420     return 0;
421 }
422
423
424 /* AES Direct mode encrypt, one block at a time */
425 int CRYPT_AES_DIRECT_Encrypt(CRYPT_AES_CTX* aes, unsigned char* out,
426                              const unsigned char* in)
427 {
428     if (aes == NULL || out == NULL || in == NULL)
429         return BAD_FUNC_ARG;
430
431     AesEncryptDirect((Aes*)aes, out, in);
432
433     return 0;
434 }
435
436
437 /* AES Direct mode decrypt, one block at a time */
438 int CRYPT_AES_DIRECT_Decrypt(CRYPT_AES_CTX* aes, unsigned char* out,
439                              const unsigned char* in)
440 {
441     if (aes == NULL || out == NULL || in == NULL)
442         return BAD_FUNC_ARG;
443
444     AesDecryptDirect((Aes*)aes, out, in);
445
446     return 0;
447 }
448
449
450 /* RSA Initialize */
451 int CRYPT_RSA_Initialize(CRYPT_RSA_CTX* rsa)
452 {
453     if (rsa == NULL)
454         return BAD_FUNC_ARG;
455
456     rsa->holder = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
457     if (rsa->holder == NULL)
458         return -1;
459
460     return InitRsaKey((RsaKey*)rsa->holder, NULL);
461 }
462
463
464 /* RSA Free resources */
465 int CRYPT_RSA_Free(CRYPT_RSA_CTX* rsa)
466 {
467     if (rsa == NULL)
468         return BAD_FUNC_ARG;
469
470     FreeRsaKey((RsaKey*)rsa->holder);
471     XFREE(rsa->holder, NULL, DYNAMIC_TYPE_RSA);
472     rsa->holder = NULL;
473
474     return 0;
475 }
476
477
478 /* RSA Public key decode ASN.1 */
479 int CRYPT_RSA_PublicKeyDecode(CRYPT_RSA_CTX* rsa, const unsigned char* in,
480                               unsigned int inSz)
481 {
482     unsigned int idx = 0;
483     (void)idx;
484
485     if (rsa == NULL || in == NULL)
486         return BAD_FUNC_ARG;
487
488     return RsaPublicKeyDecode(in, &idx, (RsaKey*)rsa->holder, inSz);
489 }
490
491
492 /* RSA Private key decode ASN.1 */
493 int CRYPT_RSA_PrivateKeyDecode(CRYPT_RSA_CTX* rsa, const unsigned char* in,
494                                unsigned int inSz)
495 {
496     unsigned int idx = 0;
497     (void)idx;
498
499     if (rsa == NULL || in == NULL)
500         return BAD_FUNC_ARG;
501
502     return RsaPrivateKeyDecode(in, &idx, (RsaKey*)rsa->holder, inSz);
503 }
504
505
506 /* RSA Public Encrypt */
507 int CRYPT_RSA_PublicEncrypt(CRYPT_RSA_CTX* rsa, unsigned char* out,
508                             unsigned int outSz, const unsigned char* in,
509                             unsigned int inSz, CRYPT_RNG_CTX* rng)
510 {
511     if (rsa == NULL || in == NULL || out == NULL || rng == NULL)
512         return BAD_FUNC_ARG;
513
514     return RsaPublicEncrypt(in, inSz, out, outSz, (RsaKey*)rsa->holder,
515                             (RNG*)rng);
516 }
517
518
519 /* RSA Private Decrypt */
520 int CRYPT_RSA_PrivateDecrypt(CRYPT_RSA_CTX* rsa, unsigned char* out,
521                              unsigned int outSz, const unsigned char* in,
522                              unsigned int inSz)
523 {
524     if (rsa == NULL || in == NULL || out == NULL)
525         return BAD_FUNC_ARG;
526
527     return RsaPrivateDecrypt(in, inSz, out, outSz, (RsaKey*)rsa->holder);
528 }
529
530
531 /* RSA Get Encrypt size helper */
532 int CRYPT_RSA_EncryptSizeGet(CRYPT_RSA_CTX* rsa) 
533 {
534     if (rsa == NULL)
535         return BAD_FUNC_ARG;
536
537     return RsaEncryptSize((RsaKey*)rsa->holder);
538 }    
539
540
541 /* ECC init */
542 int CRYPT_ECC_Initialize(CRYPT_ECC_CTX* ecc)
543 {
544     if (ecc == NULL)
545         return BAD_FUNC_ARG;
546
547     ecc->holder = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
548     if (ecc->holder == NULL)
549         return -1;
550
551     ecc_init((ecc_key*)ecc->holder);
552
553     return 0;
554 }
555
556
557 /* ECC free resources */
558 int CRYPT_ECC_Free(CRYPT_ECC_CTX* ecc)
559 {
560     if (ecc == NULL)
561         return BAD_FUNC_ARG;
562
563     ecc_free((ecc_key*)ecc->holder);
564     XFREE(ecc->holder, NULL, DYNAMIC_TYPE_ECC);
565     ecc->holder = NULL;
566
567     return 0;
568 }
569
570
571 /* ECC Public x963 Export */
572 int CRYPT_ECC_PublicExport(CRYPT_ECC_CTX* ecc, unsigned char* out,
573                            unsigned int outSz, unsigned int* usedSz)
574 {
575     int          ret;
576     unsigned int inOut = outSz;
577
578     if (ecc == NULL || out == NULL)
579         return BAD_FUNC_ARG;
580
581     ret = ecc_export_x963((ecc_key*)ecc->holder, out, &inOut);
582     *usedSz = inOut;
583
584     return ret;
585 }
586
587
588 /* ECC Public x963 Import */
589 int CRYPT_ECC_PublicImport(CRYPT_ECC_CTX* ecc, const unsigned char* in,
590                            unsigned int inSz)
591 {
592     if (ecc == NULL || in == NULL)
593         return BAD_FUNC_ARG;
594
595     return ecc_import_x963(in, inSz, (ecc_key*)ecc->holder);
596 }
597
598
599 /* ECC Private x963 Import */
600 int CRYPT_ECC_PrivateImport(CRYPT_ECC_CTX* ecc, const unsigned char* priv,
601          unsigned int privSz, const unsigned char* pub, unsigned int pubSz)
602 {
603     if (ecc == NULL || priv == NULL || pub == NULL)
604         return BAD_FUNC_ARG;
605
606     return ecc_import_private_key(priv, privSz, pub, pubSz,
607                                  (ecc_key*)ecc->holder);
608 }
609
610
611 /* ECC DHE Make key */
612 int CRYPT_ECC_DHE_KeyMake(CRYPT_ECC_CTX* ecc, CRYPT_RNG_CTX* rng, int keySz)
613 {
614     if (ecc == NULL || rng == NULL)
615         return BAD_FUNC_ARG;
616
617     return ecc_make_key((RNG*)rng, keySz, (ecc_key*)ecc->holder);
618 }
619
620
621 /* ECC DHE Make shared secret with our private and peer public */
622 int CRYPT_ECC_DHE_SharedSecretMake(CRYPT_ECC_CTX* priv, CRYPT_ECC_CTX* pub,
623                   unsigned char* out, unsigned int outSz, unsigned int* usedSz)
624 {
625     int ret;
626     unsigned int inOut = outSz;
627
628     if (priv == NULL || pub == NULL || out == NULL || usedSz == NULL)
629         return BAD_FUNC_ARG;
630
631     ret = ecc_shared_secret((ecc_key*)priv->holder, (ecc_key*)pub->holder,
632                             out, &inOut);
633     *usedSz = inOut;
634
635     return ret;
636 }
637
638
639 /* ECC DSA Hash Sign */
640 int CRYPT_ECC_DSA_HashSign(CRYPT_ECC_CTX* ecc, CRYPT_RNG_CTX* rng,
641                            unsigned char* sig, unsigned int sigSz,
642                            unsigned int* usedSz, const unsigned char* in,
643                            unsigned int inSz)
644 {
645     int ret;
646     unsigned int inOut = sigSz;
647
648     if (ecc == NULL || rng == NULL || sig == NULL || usedSz == NULL ||
649                                                                 in == NULL)
650         return BAD_FUNC_ARG;
651
652     ret = ecc_sign_hash(in, inSz, sig, &inOut, (RNG*)rng,
653                        (ecc_key*)ecc->holder);
654     *usedSz = inOut;
655
656     return ret;
657 }
658
659
660 /* ECC DSA Hash Verify */
661 int CRYPT_ECC_DSA_HashVerify(CRYPT_ECC_CTX* ecc, const unsigned char* sig,
662                              unsigned int sigSz, unsigned char* hash,
663                              unsigned int hashSz, int* status)
664 {
665     if (ecc == NULL || sig == NULL || hash == NULL || status == NULL)
666         return BAD_FUNC_ARG;
667
668     return ecc_verify_hash(sig, sigSz, hash, hashSz, status,
669                           (ecc_key*)ecc->holder);
670 }
671
672
673 /* ECC get key size helper */
674 int CRYPT_ECC_KeySizeGet(CRYPT_ECC_CTX* ecc)
675 {
676     if (ecc == NULL)
677         return BAD_FUNC_ARG;
678
679     return ecc_size((ecc_key*)ecc->holder);
680 }
681
682
683 /* ECC get signature size helper */
684 int CRYPT_ECC_SignatureSizeGet(CRYPT_ECC_CTX* ecc)
685 {
686     if (ecc == NULL)
687         return BAD_FUNC_ARG;
688
689     return ecc_sig_size((ecc_key*)ecc->holder);
690 }
691
692
693 /* Save error string from err to str which needs to be >= 80 chars */
694 int CRYPT_ERROR_StringGet(int err, char* str)
695 {
696     if (str == NULL)
697         return BAD_FUNC_ARG;
698
699     CTaoCryptErrorString(err, str);
700
701     return 0;
702 }
703