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