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