gwenhywfar 5.12.0
padd.c
Go to the documentation of this file.
1/***************************************************************************
2 begin : Mon Jan 05 2004
3 copyright : (C) 2004 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * *
8 * This library is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU Lesser General Public *
10 * License as published by the Free Software Foundation; either *
11 * version 2.1 of the License, or (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16 * Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this library; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21 * MA 02111-1307 USA *
22 * *
23 ***************************************************************************/
24
25
26#ifdef HAVE_CONFIG_H
27# include <config.h>
28#endif
29
30#define DISABLE_DEBUGLOG
31
32
33#include "padd_p.h"
34#include <gwenhywfar/misc.h>
35#include <gwenhywfar/debug.h>
36#include <gwenhywfar/error.h>
37#include <gwenhywfar/cryptdefs.h>
38#include <gwenhywfar/text.h>
39
40#include <string.h>
41#include <stdlib.h>
42
43
44static uint8_t nullarray[]= {0, 0, 0, 0, 0, 0, 0, 0};
45
46
47/*
48 * This code has been taken from OpenHBCI (rsakey.cpp, written by Fabian
49 * Kaiser)
50 */
51unsigned char GWEN_Padd_permutate(unsigned char input)
52{
53 unsigned char leftNibble;
54 unsigned char rightNibble;
55 static const unsigned char lookUp[2][16] = {
56 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
57 {14, 3, 5, 8, 9, 4, 2, 15, 0, 13, 11, 6, 7, 10, 12, 1}
58 };
59
60 rightNibble = input & 15;
61 leftNibble = input & 240;
62 leftNibble = leftNibble / 16;
63 rightNibble = lookUp[1][rightNibble];
64 leftNibble = lookUp[1][leftNibble];
65 leftNibble = leftNibble * 16;
66
67 return leftNibble + rightNibble;
68}
69
70
71
72/*
73 * The original code (in C++) has been written by Fabian Kaiser for OpenHBCI
74 * (file rsakey.cpp). Translated to C by Martin Preuss
75 */
77{
78 unsigned char *p;
79 unsigned int l;
80 unsigned int i;
81 unsigned char buffer[GWEN_PADD_ISO9796_KEYSIZE];
82 unsigned char hash[20];
83 unsigned char c;
84
85 p=(unsigned char *)GWEN_Buffer_GetStart(src);
87 memmove(hash, p, l);
88
89 /* src+src+src */
90 if (GWEN_Buffer_AppendBytes(src, (const char *)hash, l)) {
91 DBG_INFO(GWEN_LOGDOMAIN, "here");
92 return -1;
93 }
94
95 if (GWEN_Buffer_AppendBytes(src, (const char *)hash, l)) {
96 DBG_INFO(GWEN_LOGDOMAIN, "here");
97 return -1;
98 }
99
100 /* src=src(20,40) */
101 if (GWEN_Buffer_Crop(src, 20, 40)) {
102 DBG_INFO(GWEN_LOGDOMAIN, "here");
103 return -1;
104 }
105
106 memset(buffer, 0, sizeof(buffer));
107
108 /* append redundancy */
109 p=(unsigned char *)GWEN_Buffer_GetStart(src);
110 for (i=0; i<=47; i++) {
111 int j1, j2, j3;
112
113 j1=1 + sizeof(buffer) - (2*i);
114 j2=40-i;
115 j3=sizeof(buffer) - (2*i);
116
117 if (j1>=0 && j1<(int)sizeof(buffer) && j2>=0) {
118 buffer[j1]=p[j2];
119 }
120 if (j3>=0 && j3<(int)sizeof(buffer) && j2>=0) {
121 buffer[j3]=GWEN_Padd_permutate(p[j2]);
122 }
123 } /* for */
124
125 /* copy last 16 bytes to the beginning */
126 memmove(buffer, buffer+(sizeof(buffer)-16), 16);
127
128 p=buffer;
129 /* finish */
130 c=p[sizeof(buffer)-1];
131 c = (c & 15) * 16;
132 c += 6;
133 p[sizeof(buffer)-1]=c;
134 p[0] = p[0] & 127;
135 p[0] = p[0] | 64;
136 p[sizeof(buffer) - 40] = p[sizeof(buffer) - 40] ^ 1;
137
139 if (GWEN_Buffer_AppendBytes(src, (const char *)buffer, sizeof(buffer))) {
140 DBG_INFO(GWEN_LOGDOMAIN, "here");
141 return -1;
142 }
143
144 return 0;
145}
146
147
149{
150 unsigned int diff;
151 char *p;
152 int i;
153
154 if ((unsigned int)dstSize<GWEN_Buffer_GetUsedBytes(buf)+12) {
155 /*DBG_ERROR(GWEN_LOGDOMAIN, "Buffer contains too much data");*/
156 return GWEN_ERROR_INVALID;
157 }
158
159 /* add trailer */
160 GWEN_Buffer_AppendByte(buf, 0xbc);
161
162 /* reset position to 0 */
164
165 /* insert room for header */
166 diff=dstSize-GWEN_Buffer_GetUsedBytes(buf)-11+1;
167 if (GWEN_Buffer_InsertRoom(buf, 1+diff+1+8)) {
169 "Could not insert room for %d bytes",
170 1+diff+1+8);
171 return GWEN_ERROR_GENERIC;
172 }
173
174 /* insert header and more-data-bit */
176 *(p++)=0x60;
177
178 /* insert padding field */
179 for (i=0; i<diff; i++)
180 *(p++)=0x0;
181 *(p++)=0x01;
182
183 /* insert 8 random bytes */
184 GWEN_Crypt_Random(2, (uint8_t *)p, 8);
185 for (i=0; i<8; i++) {
186 if (*p==0)
187 /* TODO: Need to find a better but yet fast way */
188 *p=0xff;
189 p++;
190 }
191
192 return 0;
193}
194
195
197{
198 uint32_t l;
199 uint32_t realSize;
200 const uint8_t *p;
201
203 if (l<11) {
204 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer contains too few bytes");
205 return GWEN_ERROR_INVALID;
206 }
207
208 p=(const uint8_t *)GWEN_Buffer_GetStart(buf);
209 if (*p!=0x60) {
210 DBG_ERROR(GWEN_LOGDOMAIN, "First byte is not a 0x60");
211 return GWEN_ERROR_BAD_DATA;
212 }
213 p++;
214 l=0;
215 while (*p==0x00) {
216 l++;
217 p++;
218 }
219 if (*p!=0x01) {
220 /*DBG_ERROR(GWEN_LOGDOMAIN, "First byte after padding is not a 0x01");*/
221 return GWEN_ERROR_BAD_DATA;
222 }
223
224 realSize=GWEN_Buffer_GetUsedBytes(buf)-11-l;
225 GWEN_Buffer_Crop(buf, 10+l, realSize);
226
227 return 0;
228}
229
230
231
233{
234 unsigned char paddLength;
235 unsigned int i;
236
237 paddLength=y-(GWEN_Buffer_GetUsedBytes(src) % y);
238 for (i=0; i<paddLength; i++)
239 GWEN_Buffer_AppendByte(src, paddLength);
240 return 0;
241}
242
243
244
246{
247 const char *p;
248 unsigned int lastpos;
249 unsigned char paddLength;
250
251 lastpos=GWEN_Buffer_GetUsedBytes(src);
252 if (lastpos<y) {
253 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
254 return -1;
255 }
256 lastpos--;
257
258 p=GWEN_Buffer_GetStart(src)+lastpos;
259 paddLength=*p;
260 if (paddLength<1 || paddLength>y) {
261 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid padding (%d bytes ?)", paddLength);
262 return -1;
263 }
264 GWEN_Buffer_Crop(src, 0, GWEN_Buffer_GetUsedBytes(src)-paddLength);
265 GWEN_Buffer_SetPos(src, lastpos-paddLength);
266 return 0;
267}
268
269
270
275
276
277
282
283
284
286{
287 unsigned int diff;
288 char *p;
289
290 if ((unsigned int)dstSize<GWEN_Buffer_GetUsedBytes(buf)) {
291 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer contains too much data");
292 return GWEN_ERROR_INVALID;
293 }
294 diff=dstSize-GWEN_Buffer_GetUsedBytes(buf);
295 if (diff<11) {
296 /* honour minimum padding length for BT 1 of 8 bytes, plus the
297 * leading and the trailing zero and the block type identifier */
299 "Buffer contains too many bytes (diff is <11)");
300 return GWEN_ERROR_INVALID;
301 }
302
303 /* reset position to 0 */
305 if (GWEN_Buffer_InsertRoom(buf, diff)) {
306 DBG_ERROR(GWEN_LOGDOMAIN, "Could not insert room for %d bytes", diff);
307 return GWEN_ERROR_GENERIC;
308 }
309
311 *(p++)=0x00;
312 *(p++)=0x01; /* block type 01 */
313 if (diff>3) {
314 memset(p, 0xff, diff-3);
315 p+=diff-3;
316 }
317 *(p++)=0x00;
318
319 return 0;
320}
321
322
323
325{
326 unsigned int diff;
327 char *p;
328 int i;
329
330 if ((unsigned int)dstSize<GWEN_Buffer_GetUsedBytes(buf)) {
331 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer contains too much data");
332 return GWEN_ERROR_INVALID;
333 }
334 diff=dstSize-GWEN_Buffer_GetUsedBytes(buf);
335 if (diff<11) {
336 /* honour minimum padding length for BT 1 of 8 bytes, plus the
337 * leading and the trailing zero and the block type identifier */
339 "Buffer contains too many bytes (diff is <11)");
340 return GWEN_ERROR_INVALID;
341 }
342
343 /* reset position to 0 */
345 if (GWEN_Buffer_InsertRoom(buf, diff)) {
346 DBG_ERROR(GWEN_LOGDOMAIN, "Could not insert room for %d bytes", diff);
347 return GWEN_ERROR_GENERIC;
348 }
349
351 *(p++)=0x00;
352 *(p++)=0x02; /* block type 02 */
353 GWEN_Crypt_Random(2, (uint8_t *)p, diff-3);
354 for (i=0; i<diff-3; i++) {
355 if (*p==0)
356 /* TODO: Need to find a better but yet fast way */
357 *p=0xff;
358 p++;
359 }
360 *(p++)=0x00;
361
362 return 0;
363}
364
365
366
368{
369 char *p;
370 uint32_t len;
371 uint32_t paddBytes;
372
373 assert(buf);
375 assert(len);
376
378 if (*p==0) {
379 p++;
380 len--;
381 }
382 if (len<11) {
383 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes left (%d)", len);
384 return GWEN_ERROR_INVALID;
385 }
386
387 if (*p!=0x01 && *p!=0x02) {
388 DBG_ERROR(GWEN_LOGDOMAIN, "Unsupported block type %02x", *p);
389 return GWEN_ERROR_INVALID;
390 }
391 p++;
392 len--;
393
394 /* skip padding bytes */
395 paddBytes=0;
396 while (*p!=0x00 && len) {
397 p++;
398 len--;
399 paddBytes++;
400 }
401
402 if (*p!=0x00) {
403 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding");
404 return GWEN_ERROR_INVALID;
405 }
406 p++;
407 len--;
408
409 if (paddBytes<8) {
410 /* at least 8 padding bytes are needed */
411 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding (too few padding bytes)");
412 return GWEN_ERROR_INVALID;
413 }
414
415 GWEN_Buffer_Crop(buf, GWEN_Buffer_GetUsedBytes(buf)-len, len);
416
417 return 0;
418}
419
420
421
426
427
428
433
434
435
436int GWEN_Padd_MGF1(uint8_t *pDestBuffer,
437 uint32_t lDestBuffer,
438 const uint8_t *pSeed,
439 uint32_t lSeed,
440 GWEN_MDIGEST *md)
441{
442 uint32_t bytesLeft=lDestBuffer;
443 uint32_t i;
444 uint8_t counter[4];
445 uint8_t *p;
446
447 p=pDestBuffer;
448
449 for (i=0; bytesLeft>0; i++) {
450 int rv;
451 uint32_t l;
452
453 counter[0]= (uint8_t)((i>>24) & 0xff);
454 counter[1]= (uint8_t)((i>>16) & 0xff);
455 counter[2]= (uint8_t)((i>>8) & 0xff);
456 counter[3]= (uint8_t)(i & 0xff);
457
458 rv=GWEN_MDigest_Begin(md);
459 if (rv<0) {
460 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
461 return rv;
462 }
463
464 rv=GWEN_MDigest_Update(md, pSeed, lSeed);
465 if (rv<0) {
466 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
467 return rv;
468 }
469
470 rv=GWEN_MDigest_Update(md, counter, 4);
471 if (rv<0) {
472 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
473 return rv;
474 }
475
476 rv=GWEN_MDigest_End(md);
477 if (rv<0) {
478 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
479 return rv;
480 }
481
483 if (bytesLeft<l)
484 l=bytesLeft;
485 memmove(p, GWEN_MDigest_GetDigestPtr(md), l);
486 bytesLeft-=l;
487 p+=l;
488 }
489
490 return 0;
491}
492
493
494
495int GWEN_Padd_AddPkcs1Pss(uint8_t *pDestBuffer,
496 GWEN_UNUSED uint32_t lDestBuffer,
497 uint32_t nbits,
498 const uint8_t *pHash,
499 uint32_t lHash,
500 uint32_t lSalt,
501 GWEN_MDIGEST *md)
502{
503 uint32_t emLen;
504 uint8_t *pSalt=NULL;
505 uint8_t *pDB;
506 uint8_t *pDbMask;
507 uint32_t x;
508 uint32_t i;
509 uint8_t *p;
510 int rv;
511 uint8_t hashMBar[64];
512 int numberOfBitsInByte0;
513
514 emLen=nbits/8;
515 if (nbits%8)
516 emLen++;
517
518 /* adjust emLen because the maximum number of bits in emLen is length of modulus-1 */
519 numberOfBitsInByte0=((nbits-1) & 0x07);
520 if (numberOfBitsInByte0==0) {
521 *(pDestBuffer++)=0;
522 emLen--;
523 }
524
525 /* generate salt */
526 pSalt=(uint8_t *) malloc(lSalt);
527 assert(pSalt);
528 GWEN_Crypt_Random(2, pSalt, lSalt);
529
530 /* M'=00 00 00 00 00 00 00 00 | HASH(M) | SALT */
531 rv=GWEN_MDigest_Begin(md);
532 if (rv<0) {
533 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
534 free(pSalt);
535 return rv;
536 }
537
539 if (rv<0) {
540 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
541 free(pSalt);
542 return rv;
543 }
544
545 rv=GWEN_MDigest_Update(md, pHash, lHash);
546 if (rv<0) {
547 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
548 free(pSalt);
549 return rv;
550 }
551
552 rv=GWEN_MDigest_Update(md, pSalt, lSalt);
553 if (rv<0) {
554 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
555 free(pSalt);
556 return rv;
557 }
558
559 rv=GWEN_MDigest_End(md);
560 if (rv<0) {
561 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
562 free(pSalt);
563 return rv;
564 }
565 /* hashMBar=HASH(M') */
566 memmove(hashMBar,
569
570 /* generate DB (PS | '01' | SALT) */
571 x=emLen-GWEN_MDigest_GetDigestSize(md)-lSalt-2;
572 pDB=(uint8_t *)malloc(emLen);
573 assert(pDB);
574 p=pDB;
575 memset(p, 0, x);
576 p+=x;
577 *(p++)=0x01;
578 memmove(p, pSalt, lSalt);
579 p+=lSalt;
580
581 /* create DBMask */
582 x=emLen-GWEN_MDigest_GetDigestSize(md)-1;
583 pDbMask=(uint8_t *)malloc(x);
584 rv=GWEN_Padd_MGF1(pDbMask, x,
585 hashMBar, GWEN_MDigest_GetDigestSize(md),
586 md);
587 if (rv<0) {
588 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
589 free(pDbMask);
590 free(pDB);
591 free(pSalt);
592 return rv;
593 }
594
595 /* created maskedDB in destination buffer */
596 p=pDestBuffer;
597 for (i=0; i<x; i++)
598 *(p++)=pDB[i] ^ pDbMask[i];
599
600 /* append hashMBar */
601 memmove(p, hashMBar, GWEN_MDigest_GetDigestSize(md));
603 /* append '0xbc' */
604 *(p++)=0xbc;
605
606 /* adjust first byte */
607 if (numberOfBitsInByte0)
608 pDestBuffer[0] &= 0xff >> (8-numberOfBitsInByte0);
609
610 free(pDbMask);
611 free(pDB);
612 free(pSalt);
613
614 return emLen;
615}
616
617
618
619int GWEN_Padd_VerifyPkcs1Pss(const uint8_t *pSrcBuffer,
620 uint32_t lSrcBuffer,
621 uint32_t nbits,
622 const uint8_t *pHash,
623 uint32_t lHash,
624 uint32_t lSalt,
625 GWEN_MDIGEST *md)
626{
627 uint32_t emLen;
628 const uint8_t *pSalt;
629 uint8_t *pDB;
630 uint32_t x;
631 uint32_t i;
632 int rv;
633 const uint8_t *hashMBar;
634 int numberOfBitsInByte0;
635
636 emLen=nbits/8;
637 if (nbits%8)
638 emLen++;
639
640 /* check for leading bits to be zero */
641 numberOfBitsInByte0=((nbits-1) & 0x07);
642
643 if (numberOfBitsInByte0==0) {
644 pSrcBuffer++;
645 emLen--;
646 }
647 else {
648 if (pSrcBuffer[0] & (0xff << numberOfBitsInByte0)) {
649 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding: leading bits must be zero (%d)", numberOfBitsInByte0);
650 return GWEN_ERROR_BAD_DATA;
651 }
652 }
653
654 /* check for key length */
655 if (emLen < (GWEN_MDigest_GetDigestSize(md)+lSalt+2)) {
656 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding: Key too small for data");
657 return GWEN_ERROR_BAD_DATA;
658 }
659
660 /* check for length of provided data */
661 if (lSrcBuffer < emLen) {
662 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding: Provided data too small (is %d, expected %d)",
663 lSrcBuffer, emLen);
664 return GWEN_ERROR_BAD_DATA;
665 }
666
667 /* get DB (PS | '01' | SALT) */
668 x=emLen-GWEN_MDigest_GetDigestSize(md)-1;
669
670 pDB=(uint8_t *)malloc(x);
671 hashMBar=pSrcBuffer+x;
672 rv=GWEN_Padd_MGF1(pDB, x,
673 hashMBar, GWEN_MDigest_GetDigestSize(md),
674 md);
675 if (rv<0) {
676 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
677 free(pDB);
678 return rv;
679 }
680
681 /* un-XOR DB using DBMask from source buffer (EM) */
682 for (i=0; i<x; i++)
683 pDB[i] ^= pSrcBuffer[i];
684
685 /* check for leading bits */
686 if (numberOfBitsInByte0)
687 pDB[0] &= (0xff >> (8-numberOfBitsInByte0));
688
689 /* pDB now contains PS | '01' | SALT */
690
691 /* recover salt: skip all '00' and wait for '01' */
692 for (i=0; (i<(x-1) && pDB[i]==0); i++);
693 /* i now points to a byte which is not zero, expect it to be '01' */
694 if (pDB[i]!=0x01) {
695 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding: byte 0x01 missing before salt");
696 free(pDB);
697 return GWEN_ERROR_BAD_DATA;
698 }
699 i++;
700
701 /* check for length of salt */
702 if ((x-i)!=lSalt) {
703 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding: bad length for salt (is %d, should be %d)",
704 x-i, lSalt);
705 free(pDB);
706 return GWEN_ERROR_BAD_DATA;
707 }
708
709 /* get pointer to salt */
710 pSalt=pDB+i;
711
712 /* M'=00 00 00 00 00 00 00 00 | HASH(M) | SALT */
713 rv=GWEN_MDigest_Begin(md);
714 if (rv<0) {
715 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
716 free(pDB);
717 return rv;
718 }
719
721 if (rv<0) {
722 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
723 free(pDB);
724 return rv;
725 }
726
727 if (lHash) {
728 rv=GWEN_MDigest_Update(md, pHash, lHash);
729 if (rv<0) {
730 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
731 free(pDB);
732 return rv;
733 }
734 }
735
736 rv=GWEN_MDigest_Update(md, pSalt, lSalt);
737 if (rv<0) {
738 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
739 free(pDB);
740 return rv;
741 }
742
743 rv=GWEN_MDigest_End(md);
744 if (rv<0) {
745 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
746 free(pDB);
747 return rv;
748 }
749 if (memcmp(hashMBar,
752 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding: hash does not match");
753
754 free(pDB);
755 return GWEN_ERROR_VERIFY;
756 }
757
758 free(pDB);
759
760 DBG_INFO(GWEN_LOGDOMAIN, "Hash ok.");
761 return 0;
762}
763
764
765
767{
768 int rv;
769 unsigned int diff;
770 unsigned int bsize;
771 unsigned int dstSize;
772 unsigned int chunkSize;
774
775 assert(a);
776 assert(buf);
777
779 if (aid==GWEN_Crypt_PaddAlgoId_None)
780 /* short return if there is no padding to be done */
781 return 0;
782
784 if (chunkSize==0) {
785 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid chunk size (0)");
786 return GWEN_ERROR_INVALID;
787 }
788
789 bsize=GWEN_Buffer_GetUsedBytes(buf);
790 dstSize=bsize+(chunkSize-1);
791 dstSize=(dstSize/chunkSize)*chunkSize;
792 diff=dstSize-bsize;
793
794 DBG_INFO(GWEN_LOGDOMAIN, "Padding with algo \"%s\"",
796
797 switch (aid) {
798 case GWEN_Crypt_PaddAlgoId_None:
799 rv=0;
800 break;
801
802 case GWEN_Crypt_PaddAlgoId_Iso9796_1A4:
803 if (dstSize>96) {
805 "Padding size must be <=96 bytes (is %d)",
806 dstSize);
807 return GWEN_ERROR_INVALID;
808 }
810 break;
811
812 case GWEN_Crypt_PaddAlgoId_Pkcs1_1:
813 rv=GWEN_Padd_PaddWithPkcs1Bt1(buf, dstSize);
814 break;
815
816 case GWEN_Crypt_PaddAlgoId_Pkcs1_2:
817 rv=GWEN_Padd_PaddWithPkcs1Bt2(buf, dstSize);
818 break;
819
820 case GWEN_Crypt_PaddAlgoId_LeftZero:
821 rv=GWEN_Buffer_FillLeftWithBytes(buf, 0, diff);
822 break;
823
824 case GWEN_Crypt_PaddAlgoId_RightZero:
825 rv=GWEN_Buffer_FillWithBytes(buf, 0, diff);
826 break;
827
828 case GWEN_Crypt_PaddAlgoId_AnsiX9_23:
829 return GWEN_Padd_PaddWithAnsiX9_23(buf);
830
831 case GWEN_Crypt_PaddAlgoId_Iso9796_2:
832 return GWEN_Padd_PaddWithIso9796_2(buf, dstSize);
833
834 case GWEN_Crypt_PaddAlgoId_Iso9796_1:
835 default:
836 DBG_INFO(GWEN_LOGDOMAIN, "Algo-Type %d (%s) not supported",
839 }
840
841 if (rv) {
842 DBG_ERROR(GWEN_LOGDOMAIN, "Error padding with algo %d (%s)",
844 return GWEN_ERROR_GENERIC;
845 }
846
847 return rv;
848}
849
850
851
853{
854 int rv;
856
857 assert(a);
858 assert(buf);
859
861 DBG_INFO(GWEN_LOGDOMAIN, "Unpadding with algo \"%s\"",
863
864 switch (aid) {
865 case GWEN_Crypt_PaddAlgoId_None:
866 rv=0;
867 break;
868
869 case GWEN_Crypt_PaddAlgoId_Pkcs1_1:
871 break;
872
873 case GWEN_Crypt_PaddAlgoId_Pkcs1_2:
875 break;
876
877 case GWEN_Crypt_PaddAlgoId_AnsiX9_23:
879
880 case GWEN_Crypt_PaddAlgoId_Iso9796_2:
882
883 case GWEN_Crypt_PaddAlgoId_Iso9796_1:
884 case GWEN_Crypt_PaddAlgoId_LeftZero:
885 case GWEN_Crypt_PaddAlgoId_RightZero:
886 case GWEN_Crypt_PaddAlgoId_Iso9796_1A4:
887 default:
888 DBG_INFO(GWEN_LOGDOMAIN, "Algo-Type %d (%s) not supported",
891 }
892
893 if (rv) {
894 DBG_ERROR(GWEN_LOGDOMAIN, "Error padding with algo %d (%s)",
896 return GWEN_ERROR_GENERIC;
897 }
898
899 return rv;
900}
901
902
903
908
909
910
912{
913 unsigned char paddLength;
914 unsigned int i;
915
916 paddLength=y-(GWEN_Buffer_GetUsedBytes(src) % y);
917 if (paddLength>0) {
918 GWEN_Buffer_AppendByte(src, 0x80);
919 for (i=1; i<paddLength; i++)
920 GWEN_Buffer_AppendByte(src, 0x0);
921 }
922 return 0;
923}
924
925
926
928{
929 const uint8_t *p;
930 unsigned int lastpos;
931 unsigned char paddLength;
932 paddLength=0;
933
934 lastpos=GWEN_Buffer_GetUsedBytes(buf);
935 if (lastpos<y) {
936 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
937 return -1;
938 }
939 lastpos--;
940 p=(const uint8_t *)GWEN_Buffer_GetStart(buf)+lastpos;
941
942 while (*p==0x00) {
943 paddLength++;
944 p--;
945 }
946
947 /* first pad byte must be 0x80 */
948 if (*p==0x80) {
949 paddLength++;
950 p--;
951 }
952 else if (paddLength>0) {
953 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid padding, first pad byte has wrong value %xd (%d bytes ?)", *p, paddLength);
954 return -1;
955 }
956
957 if (paddLength<0 || paddLength>y) {
958 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid padding (%d bytes ?)", paddLength);
959 return -1;
960 }
961 GWEN_Buffer_Crop(buf, 0, GWEN_Buffer_GetUsedBytes(buf)-paddLength);
962 GWEN_Buffer_SetPos(buf, lastpos-paddLength);
963 return 0;
964}
965
966
967
972
973
#define NULL
Definition binreloc.c:300
int GWEN_Buffer_FillWithBytes(GWEN_BUFFER *bf, unsigned char c, uint32_t size)
Definition buffer.c:1012
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
Definition buffer.c:653
int GWEN_Buffer_SetPos(GWEN_BUFFER *bf, uint32_t i)
Definition buffer.c:261
void GWEN_Buffer_Rewind(GWEN_BUFFER *bf)
Definition buffer.c:663
int GWEN_Buffer_InsertRoom(GWEN_BUFFER *bf, uint32_t size)
Definition buffer.c:739
int GWEN_Buffer_AppendBytes(GWEN_BUFFER *bf, const char *buffer, uint32_t size)
Definition buffer.c:360
int GWEN_Buffer_FillLeftWithBytes(GWEN_BUFFER *bf, unsigned char c, uint32_t size)
Definition buffer.c:1044
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition buffer.c:277
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition buffer.c:235
int GWEN_Buffer_Crop(GWEN_BUFFER *bf, uint32_t pos, uint32_t l)
Definition buffer.c:950
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition buffer.c:393
void GWEN_Crypt_Random(int quality, uint8_t *buffer, uint32_t len)
Definition cryptdefs.c:551
#define DBG_INFO(dbg_logger, format,...)
Definition debug.h:181
#define DBG_ERROR(dbg_logger, format,...)
Definition debug.h:97
#define GWEN_ERROR_VERIFY
Definition error.h:104
#define GWEN_ERROR_INVALID
Definition error.h:67
#define GWEN_ERROR_BAD_DATA
Definition error.h:121
#define GWEN_ERROR_GENERIC
Definition error.h:62
#define GWEN_ERROR_NOT_AVAILABLE
Definition error.h:64
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition buffer.h:38
#define GWEN_UNUSED
#define GWEN_LOGDOMAIN
Definition logger.h:35
int GWEN_MDigest_Begin(GWEN_MDIGEST *md)
Definition mdigest.c:129
int GWEN_MDigest_End(GWEN_MDIGEST *md)
Definition mdigest.c:141
unsigned int GWEN_MDigest_GetDigestSize(GWEN_MDIGEST *md)
Definition mdigest.c:90
uint8_t * GWEN_MDigest_GetDigestPtr(GWEN_MDIGEST *md)
Definition mdigest.c:81
int GWEN_MDigest_Update(GWEN_MDIGEST *md, const uint8_t *buf, unsigned int l)
Definition mdigest.c:153
struct GWEN_MDIGEST GWEN_MDIGEST
Definition mdigest.h:25
int GWEN_Padd_PaddWithIso9796_2(GWEN_BUFFER *buf, int dstSize)
Definition padd.c:148
int GWEN_Padd_PaddWithPkcs1Bt1(GWEN_BUFFER *buf, int dstSize)
Definition padd.c:285
int GWEN_Padd_UnpaddWithZka(GWEN_BUFFER *buf)
Definition padd.c:968
int GWEN_Padd_PaddWithPkcs1Bt2(GWEN_BUFFER *buf, int dstSize)
Definition padd.c:324
int GWEN_Padd_PaddWithAnsiX9_23(GWEN_BUFFER *src)
Definition padd.c:271
int GWEN_Padd_VerifyPkcs1Pss(const uint8_t *pSrcBuffer, uint32_t lSrcBuffer, uint32_t nbits, const uint8_t *pHash, uint32_t lHash, uint32_t lSalt, GWEN_MDIGEST *md)
Definition padd.c:619
int GWEN_Padd_PaddWithISO9796(GWEN_BUFFER *src)
Definition padd.c:76
int GWEN_Padd__UnpaddWithPkcs1Bt1Or2(GWEN_BUFFER *buf)
Definition padd.c:367
int GWEN_Padd_UnpaddWithPkcs1Bt2(GWEN_BUFFER *src)
Definition padd.c:429
int GWEN_Padd_UnpaddWithIso9796_2(GWEN_BUFFER *buf)
Definition padd.c:196
int GWEN_Padd_PaddWithZka(GWEN_BUFFER *src)
Definition padd.c:904
int GWEN_Padd_MGF1(uint8_t *pDestBuffer, uint32_t lDestBuffer, const uint8_t *pSeed, uint32_t lSeed, GWEN_MDIGEST *md)
Definition padd.c:436
int GWEN_Padd_UnpaddWithAnsiX9_23(GWEN_BUFFER *src)
Definition padd.c:278
int GWEN_Padd_UnapplyPaddAlgo(const GWEN_CRYPT_PADDALGO *a, GWEN_BUFFER *buf)
Definition padd.c:852
unsigned char GWEN_Padd_permutate(unsigned char input)
Definition padd.c:51
int GWEN_Padd_PaddWithZkaToMultipleOf(GWEN_BUFFER *src, int y)
Definition padd.c:911
int GWEN_Padd_AddPkcs1Pss(uint8_t *pDestBuffer, GWEN_UNUSED uint32_t lDestBuffer, uint32_t nbits, const uint8_t *pHash, uint32_t lHash, uint32_t lSalt, GWEN_MDIGEST *md)
Definition padd.c:495
int GWEN_Padd_UnpaddWithAnsiX9_23FromMultipleOf(GWEN_BUFFER *src, int y)
Definition padd.c:245
int GWEN_Padd_UnpaddWithZkaFromMultipleOf(GWEN_BUFFER *buf, int y)
Definition padd.c:927
int GWEN_Padd_UnpaddWithPkcs1Bt1(GWEN_BUFFER *src)
Definition padd.c:422
static uint8_t nullarray[]
Definition padd.c:44
int GWEN_Padd_PaddWithAnsiX9_23ToMultipleOf(GWEN_BUFFER *src, int y)
Definition padd.c:232
int GWEN_Padd_ApplyPaddAlgo(const GWEN_CRYPT_PADDALGO *a, GWEN_BUFFER *buf)
Definition padd.c:766
const char * GWEN_Crypt_PaddAlgoId_toString(GWEN_CRYPT_PADDALGOID a)
Definition paddalgo.c:58
int GWEN_Crypt_PaddAlgo_GetPaddSize(const GWEN_CRYPT_PADDALGO *a)
Definition paddalgo.c:195
GWEN_CRYPT_PADDALGOID GWEN_Crypt_PaddAlgo_GetId(const GWEN_CRYPT_PADDALGO *a)
Definition paddalgo.c:186
struct GWEN_CRYPT_PADDALGO GWEN_CRYPT_PADDALGO
Definition paddalgo.h:21
GWEN_CRYPT_PADDALGOID
Definition paddalgo.h:60