00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifdef HAVE_CONFIG_H
00027 # include <config.h>
00028 #endif
00029
00030 #define DISABLE_DEBUGLOG
00031
00032
00033 #include "padd_p.h"
00034 #include <gwenhywfar/misc.h>
00035 #include <gwenhywfar/debug.h>
00036 #include <gwenhywfar/error.h>
00037 #include <gwenhywfar/cryptdefs.h>
00038 #include <gwenhywfar/text.h>
00039
00040 #include <string.h>
00041 #include <stdlib.h>
00042
00043
00044 static uint8_t nullarray[]={0, 0, 0, 0, 0, 0, 0, 0};
00045
00046
00047
00048
00049
00050
00051 unsigned char GWEN_Padd_permutate(unsigned char input) {
00052 unsigned char leftNibble;
00053 unsigned char rightNibble;
00054 static const unsigned char lookUp[2][16] =
00055 {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},
00056 {14,3,5,8,9,4,2,15,0,13,11,6,7,10,12,1}};
00057
00058 rightNibble = input & 15;
00059 leftNibble = input & 240;
00060 leftNibble = leftNibble / 16;
00061 rightNibble = lookUp[1][rightNibble];
00062 leftNibble = lookUp[1][leftNibble];
00063 leftNibble = leftNibble * 16;
00064
00065 return leftNibble + rightNibble;
00066 }
00067
00068
00069
00070
00071
00072
00073
00074 int GWEN_Padd_PaddWithISO9796(GWEN_BUFFER *src) {
00075 unsigned char *p;
00076 unsigned int l;
00077 unsigned int i;
00078 unsigned char buffer[GWEN_PADD_ISO9796_KEYSIZE];
00079 unsigned char hash[20];
00080 unsigned char c;
00081
00082 p=(unsigned char*)GWEN_Buffer_GetStart(src);
00083 l=GWEN_Buffer_GetUsedBytes(src);
00084 memmove(hash, p, l);
00085
00086
00087 if (GWEN_Buffer_AppendBytes(src, (const char*)hash, l)) {
00088 DBG_INFO(GWEN_LOGDOMAIN, "here");
00089 return -1;
00090 }
00091
00092 if (GWEN_Buffer_AppendBytes(src, (const char*)hash, l)) {
00093 DBG_INFO(GWEN_LOGDOMAIN, "here");
00094 return -1;
00095 }
00096
00097
00098 if (GWEN_Buffer_Crop(src, 20, 40)) {
00099 DBG_INFO(GWEN_LOGDOMAIN, "here");
00100 return -1;
00101 }
00102
00103 memset(buffer, 0, sizeof(buffer));
00104
00105
00106 p=(unsigned char*)GWEN_Buffer_GetStart(src);
00107 for (i=0; i<=47; i++) {
00108 int j1, j2, j3;
00109
00110 j1=1 + sizeof(buffer) - (2*i);
00111 j2=40-i;
00112 j3=sizeof(buffer) - (2*i);
00113
00114 if (j1>=0 && j1<(int)sizeof(buffer) && j2>=0) {
00115 buffer[j1]=p[j2];
00116 }
00117 if (j3>=0 && j3<(int)sizeof(buffer) && j2>=0) {
00118 buffer[j3]=GWEN_Padd_permutate(p[j2]);
00119 }
00120 }
00121
00122
00123 memmove(buffer, buffer+(sizeof(buffer)-16), 16);
00124
00125 p=buffer;
00126
00127 c=p[sizeof(buffer)-1];
00128 c = (c & 15) * 16;
00129 c += 6;
00130 p[sizeof(buffer)-1]=c;
00131 p[0] = p[0] & 127;
00132 p[0] = p[0] | 64;
00133 p[sizeof(buffer) - 40] = p[sizeof(buffer) - 40] ^ 1;
00134
00135 GWEN_Buffer_Reset(src);
00136 if (GWEN_Buffer_AppendBytes(src, (const char*)buffer, sizeof(buffer))) {
00137 DBG_INFO(GWEN_LOGDOMAIN, "here");
00138 return -1;
00139 }
00140
00141 return 0;
00142 }
00143
00144
00145 int GWEN_Padd_PaddWithIso9796_2(GWEN_BUFFER *buf, int dstSize){
00146 unsigned int diff;
00147 char *p;
00148 int i;
00149
00150 if ((unsigned int)dstSize<GWEN_Buffer_GetUsedBytes(buf)+12) {
00151
00152 return GWEN_ERROR_INVALID;
00153 }
00154
00155
00156 GWEN_Buffer_AppendByte(buf, 0xbc);
00157
00158
00159 GWEN_Buffer_Rewind(buf);
00160
00161
00162 diff=dstSize-GWEN_Buffer_GetUsedBytes(buf)-11+1;
00163 if (GWEN_Buffer_InsertRoom(buf, 1+diff+1+8)) {
00164 DBG_ERROR(GWEN_LOGDOMAIN,
00165 "Could not insert room for %d bytes",
00166 1+diff+1+8);
00167 return GWEN_ERROR_GENERIC;
00168 }
00169
00170
00171 p=GWEN_Buffer_GetStart(buf);
00172 *(p++)=0x60;
00173
00174
00175 for (i=0; i<diff; i++)
00176 *(p++)=0x0;
00177 *(p++)=0x01;
00178
00179
00180 GWEN_Crypt_Random(2, (uint8_t*)p, 8);
00181 for (i=0; i<8; i++) {
00182 if (*p==0)
00183
00184 *p=0xff;
00185 p++;
00186 }
00187
00188 return 0;
00189 }
00190
00191
00192 int GWEN_Padd_UnpaddWithIso9796_2(GWEN_BUFFER *buf){
00193 uint32_t l;
00194 uint32_t realSize;
00195 const uint8_t *p;
00196
00197 l=GWEN_Buffer_GetUsedBytes(buf);
00198 if (l<11) {
00199 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer contains too few bytes");
00200 return GWEN_ERROR_INVALID;
00201 }
00202
00203 p=(const uint8_t*)GWEN_Buffer_GetStart(buf);
00204 if (*p!=0x60) {
00205 DBG_ERROR(GWEN_LOGDOMAIN, "First byte is not a 0x60");
00206 return GWEN_ERROR_BAD_DATA;
00207 }
00208 p++;
00209 l=0;
00210 while(*p==0x00) {
00211 l++;
00212 p++;
00213 }
00214 if (*p!=0x01) {
00215
00216 return GWEN_ERROR_BAD_DATA;
00217 }
00218
00219 realSize=GWEN_Buffer_GetUsedBytes(buf)-11-l;
00220 GWEN_Buffer_Crop(buf, 10+l, realSize);
00221
00222 return 0;
00223 }
00224
00225
00226
00227 int GWEN_Padd_PaddWithAnsiX9_23ToMultipleOf(GWEN_BUFFER *src, int y) {
00228 unsigned char paddLength;
00229 unsigned int i;
00230
00231 paddLength=y-(GWEN_Buffer_GetUsedBytes(src) % y);
00232 for (i=0; i<paddLength; i++)
00233 GWEN_Buffer_AppendByte(src, paddLength);
00234 return 0;
00235 }
00236
00237
00238
00239 int GWEN_Padd_UnpaddWithAnsiX9_23FromMultipleOf(GWEN_BUFFER *src, int y) {
00240 const char *p;
00241 unsigned int lastpos;
00242 unsigned char paddLength;
00243
00244 lastpos=GWEN_Buffer_GetUsedBytes(src);
00245 if (lastpos<y) {
00246 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
00247 return -1;
00248 }
00249 lastpos--;
00250
00251 p=GWEN_Buffer_GetStart(src)+lastpos;
00252 paddLength=*p;
00253 if (paddLength<1 || paddLength>y) {
00254 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid padding (%d bytes ?)", paddLength);
00255 return -1;
00256 }
00257 GWEN_Buffer_Crop(src, 0, GWEN_Buffer_GetUsedBytes(src)-paddLength);
00258 GWEN_Buffer_SetPos(src, lastpos-paddLength);
00259 return 0;
00260 }
00261
00262
00263
00264 int GWEN_Padd_PaddWithAnsiX9_23(GWEN_BUFFER *src) {
00265 return GWEN_Padd_PaddWithAnsiX9_23ToMultipleOf(src, 8);
00266 }
00267
00268
00269
00270 int GWEN_Padd_UnpaddWithAnsiX9_23(GWEN_BUFFER *src) {
00271 return GWEN_Padd_UnpaddWithAnsiX9_23FromMultipleOf(src, 8);
00272 }
00273
00274
00275
00276 int GWEN_Padd_PaddWithPkcs1Bt1(GWEN_BUFFER *buf, int dstSize){
00277 unsigned int diff;
00278 char *p;
00279
00280 if ((unsigned int)dstSize<GWEN_Buffer_GetUsedBytes(buf)) {
00281 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer contains too much data");
00282 return GWEN_ERROR_INVALID;
00283 }
00284 diff=dstSize-GWEN_Buffer_GetUsedBytes(buf);
00285 if (diff<11) {
00286
00287
00288 DBG_ERROR(GWEN_LOGDOMAIN,
00289 "Buffer contains too many bytes (diff is <11)");
00290 return GWEN_ERROR_INVALID;
00291 }
00292
00293
00294 GWEN_Buffer_Rewind(buf);
00295 if (GWEN_Buffer_InsertRoom(buf, diff)) {
00296 DBG_ERROR(GWEN_LOGDOMAIN, "Could not insert room for %d bytes", diff);
00297 return GWEN_ERROR_GENERIC;
00298 }
00299
00300 p=GWEN_Buffer_GetStart(buf);
00301 *(p++)=0x00;
00302 *(p++)=0x01;
00303 if (diff>3) {
00304 memset(p, 0xff, diff-3);
00305 p+=diff-3;
00306 }
00307 *(p++)=0x00;
00308
00309 return 0;
00310 }
00311
00312
00313
00314 int GWEN_Padd_PaddWithPkcs1Bt2(GWEN_BUFFER *buf, int dstSize){
00315 unsigned int diff;
00316 char *p;
00317 int i;
00318
00319 if ((unsigned int)dstSize<GWEN_Buffer_GetUsedBytes(buf)) {
00320 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer contains too much data");
00321 return GWEN_ERROR_INVALID;
00322 }
00323 diff=dstSize-GWEN_Buffer_GetUsedBytes(buf);
00324 if (diff<11) {
00325
00326
00327 DBG_ERROR(GWEN_LOGDOMAIN,
00328 "Buffer contains too many bytes (diff is <11)");
00329 return GWEN_ERROR_INVALID;
00330 }
00331
00332
00333 GWEN_Buffer_Rewind(buf);
00334 if (GWEN_Buffer_InsertRoom(buf, diff)) {
00335 DBG_ERROR(GWEN_LOGDOMAIN, "Could not insert room for %d bytes", diff);
00336 return GWEN_ERROR_GENERIC;
00337 }
00338
00339 p=GWEN_Buffer_GetStart(buf);
00340 *(p++)=0x00;
00341 *(p++)=0x02;
00342 GWEN_Crypt_Random(2, (uint8_t*)p, diff-3);
00343 for (i=0; i<diff-3; i++) {
00344 if (*p==0)
00345
00346 *p=0xff;
00347 p++;
00348 }
00349 *(p++)=0x00;
00350
00351 return 0;
00352 }
00353
00354
00355
00356 int GWEN_Padd__UnpaddWithPkcs1Bt1Or2(GWEN_BUFFER *buf) {
00357 char *p;
00358 uint32_t len;
00359 uint32_t paddBytes;
00360
00361 assert(buf);
00362 len=GWEN_Buffer_GetUsedBytes(buf);
00363 assert(len);
00364
00365 p=GWEN_Buffer_GetStart(buf);
00366 if (*p==0) {
00367 p++;
00368 len--;
00369 }
00370 if (len<11) {
00371 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes left (%d)", len);
00372 return GWEN_ERROR_INVALID;
00373 }
00374
00375 if (*p!=0x01 && *p!=0x02) {
00376 DBG_ERROR(GWEN_LOGDOMAIN, "Unsupported block type %02x", *p);
00377 return GWEN_ERROR_INVALID;
00378 }
00379 p++; len--;
00380
00381
00382 paddBytes=0;
00383 while(*p!=0x00 && len) {
00384 p++; len--;
00385 paddBytes++;
00386 }
00387
00388 if (*p!=0x00) {
00389 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding");
00390 return GWEN_ERROR_INVALID;
00391 }
00392 p++; len--;
00393
00394 if (paddBytes<8) {
00395
00396 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding (too few padding bytes)");
00397 return GWEN_ERROR_INVALID;
00398 }
00399
00400 GWEN_Buffer_Crop(buf, GWEN_Buffer_GetUsedBytes(buf)-len, len);
00401
00402 return 0;
00403 }
00404
00405
00406
00407 int GWEN_Padd_UnpaddWithPkcs1Bt1(GWEN_BUFFER *src){
00408 return GWEN_Padd__UnpaddWithPkcs1Bt1Or2(src);
00409 }
00410
00411
00412
00413 int GWEN_Padd_UnpaddWithPkcs1Bt2(GWEN_BUFFER *src){
00414 return GWEN_Padd__UnpaddWithPkcs1Bt1Or2(src);
00415 }
00416
00417
00418
00419 int GWEN_Padd_MGF1(uint8_t *pDestBuffer,
00420 uint32_t lDestBuffer,
00421 const uint8_t *pSeed,
00422 uint32_t lSeed,
00423 GWEN_MDIGEST *md) {
00424 uint32_t bytesLeft=lDestBuffer;
00425 uint32_t i;
00426 uint8_t counter[4];
00427 uint8_t *p;
00428
00429 p=pDestBuffer;
00430
00431 for (i=0; bytesLeft>0; i++) {
00432 int rv;
00433 uint32_t l;
00434
00435 counter[0]= (uint8_t)((i>>24) & 0xff);
00436 counter[1]= (uint8_t)((i>>16) & 0xff);
00437 counter[2]= (uint8_t)((i>>8) & 0xff);
00438 counter[3]= (uint8_t)(i & 0xff);
00439
00440 rv=GWEN_MDigest_Begin(md);
00441 if (rv<0) {
00442 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00443 return rv;
00444 }
00445
00446 rv=GWEN_MDigest_Update(md, pSeed, lSeed);
00447 if (rv<0) {
00448 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00449 return rv;
00450 }
00451
00452 rv=GWEN_MDigest_Update(md, counter, 4);
00453 if (rv<0) {
00454 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00455 return rv;
00456 }
00457
00458 rv=GWEN_MDigest_End(md);
00459 if (rv<0) {
00460 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00461 return rv;
00462 }
00463
00464 l=GWEN_MDigest_GetDigestSize(md);
00465 if (bytesLeft<l)
00466 l=bytesLeft;
00467 memmove(p, GWEN_MDigest_GetDigestPtr(md), l);
00468 bytesLeft-=l;
00469 p+=l;
00470 }
00471
00472 return 0;
00473 }
00474
00475
00476
00477 int GWEN_Padd_AddPkcs1Pss(uint8_t *pDestBuffer,
00478 uint32_t lDestBuffer,
00479 uint32_t nbits,
00480 const uint8_t *pHash,
00481 uint32_t lHash,
00482 uint32_t lSalt,
00483 GWEN_MDIGEST *md) {
00484 uint32_t emLen;
00485 uint8_t *pSalt=NULL;
00486 uint8_t *pDB;
00487 uint8_t *pDbMask;
00488 uint32_t x;
00489 uint32_t i;
00490 uint8_t *p;
00491 int rv;
00492 uint8_t hashMBar[64];
00493 int numberOfBitsInByte0;
00494
00495 emLen=nbits/8;
00496 if (nbits%8)
00497 emLen++;
00498
00499
00500 numberOfBitsInByte0=((nbits-1) & 0x07);
00501 if (numberOfBitsInByte0==0) {
00502 *(pDestBuffer++)=0;
00503 emLen--;
00504 }
00505
00506
00507 pSalt=(uint8_t*) malloc(lSalt);
00508 assert(pSalt);
00509 GWEN_Crypt_Random(2, pSalt, lSalt);
00510
00511
00512 rv=GWEN_MDigest_Begin(md);
00513 if (rv<0) {
00514 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00515 free(pSalt);
00516 return rv;
00517 }
00518
00519 rv=GWEN_MDigest_Update(md, nullarray, 8);
00520 if (rv<0) {
00521 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00522 free(pSalt);
00523 return rv;
00524 }
00525
00526 rv=GWEN_MDigest_Update(md, pHash, lHash);
00527 if (rv<0) {
00528 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00529 free(pSalt);
00530 return rv;
00531 }
00532
00533 rv=GWEN_MDigest_Update(md, pSalt, lSalt);
00534 if (rv<0) {
00535 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00536 free(pSalt);
00537 return rv;
00538 }
00539
00540 rv=GWEN_MDigest_End(md);
00541 if (rv<0) {
00542 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00543 free(pSalt);
00544 return rv;
00545 }
00546
00547 memmove(hashMBar,
00548 GWEN_MDigest_GetDigestPtr(md),
00549 GWEN_MDigest_GetDigestSize(md));
00550
00551
00552 x=emLen-GWEN_MDigest_GetDigestSize(md)-lSalt-2;
00553 pDB=(uint8_t*)malloc(emLen);
00554 assert(pDB);
00555 p=pDB;
00556 memset(p, 0, x);
00557 p+=x;
00558 *(p++)=0x01;
00559 memmove(p, pSalt, lSalt);
00560 p+=lSalt;
00561
00562
00563 x=emLen-GWEN_MDigest_GetDigestSize(md)-1;
00564 pDbMask=(uint8_t*)malloc(x);
00565 rv=GWEN_Padd_MGF1(pDbMask, x,
00566 hashMBar, GWEN_MDigest_GetDigestSize(md),
00567 md);
00568 if (rv<0) {
00569 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00570 free(pDbMask);
00571 free(pDB);
00572 free(pSalt);
00573 return rv;
00574 }
00575
00576
00577 p=pDestBuffer;
00578 for (i=0; i<x; i++)
00579 *(p++)=pDB[i] ^ pDbMask[i];
00580
00581
00582 memmove(p, hashMBar, GWEN_MDigest_GetDigestSize(md));
00583 p+=GWEN_MDigest_GetDigestSize(md);
00584
00585 *(p++)=0xbc;
00586
00587
00588 if (numberOfBitsInByte0)
00589 pDestBuffer[0] &= 0xff >> (8-numberOfBitsInByte0);
00590
00591 free(pDbMask);
00592 free(pDB);
00593 free(pSalt);
00594
00595 return emLen;
00596 }
00597
00598
00599
00600 int GWEN_Padd_VerifyPkcs1Pss(const uint8_t *pSrcBuffer,
00601 uint32_t lSrcBuffer,
00602 uint32_t nbits,
00603 const uint8_t *pHash,
00604 uint32_t lHash,
00605 uint32_t lSalt,
00606 GWEN_MDIGEST *md) {
00607 uint32_t emLen;
00608 const uint8_t *pSalt;
00609 uint8_t *pDB;
00610 uint32_t x;
00611 uint32_t i;
00612 int rv;
00613 const uint8_t *hashMBar;
00614 int numberOfBitsInByte0;
00615
00616 emLen=nbits/8;
00617 if (nbits%8)
00618 emLen++;
00619
00620
00621 numberOfBitsInByte0=((nbits-1) & 0x07);
00622
00623 if (numberOfBitsInByte0==0) {
00624 pSrcBuffer++;
00625 emLen--;
00626 }
00627 else {
00628 if (pSrcBuffer[0] & (0xff << numberOfBitsInByte0)) {
00629 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding: leading bits must be zero (%d)", numberOfBitsInByte0);
00630 return GWEN_ERROR_BAD_DATA;
00631 }
00632 }
00633
00634
00635 if (emLen < (GWEN_MDigest_GetDigestSize(md)+lSalt+2)) {
00636 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding: Key too small for data");
00637 return GWEN_ERROR_BAD_DATA;
00638 }
00639
00640
00641 if (lSrcBuffer < emLen) {
00642 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding: Provided data too small (is %d, expected %d)",
00643 lSrcBuffer, emLen);
00644 return GWEN_ERROR_BAD_DATA;
00645 }
00646
00647
00648 x=emLen-GWEN_MDigest_GetDigestSize(md)-1;
00649
00650 pDB=(uint8_t*)malloc(x);
00651 hashMBar=pSrcBuffer+x;
00652 rv=GWEN_Padd_MGF1(pDB, x,
00653 hashMBar, GWEN_MDigest_GetDigestSize(md),
00654 md);
00655 if (rv<0) {
00656 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00657 free(pDB);
00658 return rv;
00659 }
00660
00661
00662 for (i=0; i<x; i++)
00663 pDB[i] ^= pSrcBuffer[i];
00664
00665
00666 if (numberOfBitsInByte0)
00667 pDB[0] &= (0xff >> (8-numberOfBitsInByte0));
00668
00669
00670
00671
00672 for (i=0; (i<(x-1) && pDB[i]==0); i++);
00673
00674 if (pDB[i]!=0x01) {
00675 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding: byte 0x01 missing before salt");
00676 free(pDB);
00677 return GWEN_ERROR_BAD_DATA;
00678 }
00679 i++;
00680
00681
00682 if ((x-i)!=lSalt) {
00683 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding: bad length for salt (is %d, should be %d)",
00684 x-i, lSalt);
00685 free(pDB);
00686 return GWEN_ERROR_BAD_DATA;
00687 }
00688
00689
00690 pSalt=pDB+i;
00691
00692
00693 rv=GWEN_MDigest_Begin(md);
00694 if (rv<0) {
00695 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00696 free(pDB);
00697 return rv;
00698 }
00699
00700 rv=GWEN_MDigest_Update(md, nullarray, 8);
00701 if (rv<0) {
00702 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00703 free(pDB);
00704 return rv;
00705 }
00706
00707 if (lHash) {
00708 rv=GWEN_MDigest_Update(md, pHash, lHash);
00709 if (rv<0) {
00710 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00711 free(pDB);
00712 return rv;
00713 }
00714 }
00715
00716 rv=GWEN_MDigest_Update(md, pSalt, lSalt);
00717 if (rv<0) {
00718 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00719 free(pDB);
00720 return rv;
00721 }
00722
00723 rv=GWEN_MDigest_End(md);
00724 if (rv<0) {
00725 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00726 free(pDB);
00727 return rv;
00728 }
00729 if (memcmp(hashMBar,
00730 GWEN_MDigest_GetDigestPtr(md),
00731 GWEN_MDigest_GetDigestSize(md))!=0) {
00732 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding: hash does not match");
00733
00734 free(pDB);
00735 return GWEN_ERROR_VERIFY;
00736 }
00737
00738 free(pDB);
00739
00740 DBG_INFO(GWEN_LOGDOMAIN, "Hash ok.");
00741 return 0;
00742 }
00743
00744
00745
00746 int GWEN_Padd_ApplyPaddAlgo(const GWEN_CRYPT_PADDALGO *a, GWEN_BUFFER *buf) {
00747 int rv;
00748 unsigned int diff;
00749 unsigned int bsize;
00750 unsigned int dstSize;
00751 unsigned int chunkSize;
00752 GWEN_CRYPT_PADDALGOID aid;
00753
00754 assert(a);
00755 assert(buf);
00756
00757 aid=GWEN_Crypt_PaddAlgo_GetId(a);
00758 if (aid==GWEN_Crypt_PaddAlgoId_None)
00759
00760 return 0;
00761
00762 chunkSize=GWEN_Crypt_PaddAlgo_GetPaddSize(a);
00763 if (chunkSize==0) {
00764 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid chunk size (0)");
00765 return GWEN_ERROR_INVALID;
00766 }
00767
00768 bsize=GWEN_Buffer_GetUsedBytes(buf);
00769 dstSize=bsize+(chunkSize-1);
00770 dstSize=(dstSize/chunkSize)*chunkSize;
00771 diff=dstSize-bsize;
00772
00773 DBG_INFO(GWEN_LOGDOMAIN, "Padding with algo \"%s\"",
00774 GWEN_Crypt_PaddAlgoId_toString(aid));
00775
00776 switch(aid) {
00777 case GWEN_Crypt_PaddAlgoId_None:
00778 rv=0;
00779 break;
00780
00781 case GWEN_Crypt_PaddAlgoId_Iso9796_1A4:
00782 if (dstSize>96) {
00783 DBG_ERROR(GWEN_LOGDOMAIN,
00784 "Padding size must be <=96 bytes (is %d)",
00785 dstSize);
00786 return GWEN_ERROR_INVALID;
00787 }
00788 rv=GWEN_Padd_PaddWithISO9796(buf);
00789 break;
00790
00791 case GWEN_Crypt_PaddAlgoId_Pkcs1_1:
00792 rv=GWEN_Padd_PaddWithPkcs1Bt1(buf, dstSize);
00793 break;
00794
00795 case GWEN_Crypt_PaddAlgoId_Pkcs1_2:
00796 rv=GWEN_Padd_PaddWithPkcs1Bt2(buf, dstSize);
00797 break;
00798
00799 case GWEN_Crypt_PaddAlgoId_LeftZero:
00800 rv=GWEN_Buffer_FillLeftWithBytes(buf, 0, diff);
00801 break;
00802
00803 case GWEN_Crypt_PaddAlgoId_RightZero:
00804 rv=GWEN_Buffer_FillWithBytes(buf, 0, diff);
00805 break;
00806
00807 case GWEN_Crypt_PaddAlgoId_AnsiX9_23:
00808 return GWEN_Padd_PaddWithAnsiX9_23(buf);
00809
00810 case GWEN_Crypt_PaddAlgoId_Iso9796_2:
00811 return GWEN_Padd_PaddWithIso9796_2(buf, dstSize);
00812
00813 case GWEN_Crypt_PaddAlgoId_Iso9796_1:
00814 default:
00815 DBG_INFO(GWEN_LOGDOMAIN, "Algo-Type %d (%s) not supported",
00816 aid, GWEN_Crypt_PaddAlgoId_toString(aid));
00817 return GWEN_ERROR_NOT_AVAILABLE;
00818 }
00819
00820 if (rv) {
00821 DBG_ERROR(GWEN_LOGDOMAIN, "Error padding with algo %d (%s)",
00822 aid, GWEN_Crypt_PaddAlgoId_toString(aid));
00823 return GWEN_ERROR_GENERIC;
00824 }
00825
00826 return rv;
00827 }
00828
00829
00830
00831 int GWEN_Padd_UnapplyPaddAlgo(const GWEN_CRYPT_PADDALGO *a, GWEN_BUFFER *buf){
00832 int rv;
00833 GWEN_CRYPT_PADDALGOID aid;
00834
00835 assert(a);
00836 assert(buf);
00837
00838 aid=GWEN_Crypt_PaddAlgo_GetId(a);
00839 DBG_INFO(GWEN_LOGDOMAIN, "Unpadding with algo \"%s\"",
00840 GWEN_Crypt_PaddAlgoId_toString(aid));
00841
00842 switch(aid) {
00843 case GWEN_Crypt_PaddAlgoId_None:
00844 rv=0;
00845 break;
00846
00847 case GWEN_Crypt_PaddAlgoId_Pkcs1_1:
00848 rv=GWEN_Padd_UnpaddWithPkcs1Bt1(buf);
00849 break;
00850
00851 case GWEN_Crypt_PaddAlgoId_Pkcs1_2:
00852 rv=GWEN_Padd_UnpaddWithPkcs1Bt2(buf);
00853 break;
00854
00855 case GWEN_Crypt_PaddAlgoId_AnsiX9_23:
00856 return GWEN_Padd_UnpaddWithAnsiX9_23(buf);
00857
00858 case GWEN_Crypt_PaddAlgoId_Iso9796_2:
00859 return GWEN_Padd_UnpaddWithIso9796_2(buf);
00860
00861 case GWEN_Crypt_PaddAlgoId_Iso9796_1:
00862 case GWEN_Crypt_PaddAlgoId_LeftZero:
00863 case GWEN_Crypt_PaddAlgoId_RightZero:
00864 case GWEN_Crypt_PaddAlgoId_Iso9796_1A4:
00865 default:
00866 DBG_INFO(GWEN_LOGDOMAIN, "Algo-Type %d (%s) not supported",
00867 aid, GWEN_Crypt_PaddAlgoId_toString(aid));
00868 return GWEN_ERROR_NOT_AVAILABLE;
00869 }
00870
00871 if (rv) {
00872 DBG_ERROR(GWEN_LOGDOMAIN, "Error padding with algo %d (%s)",
00873 aid, GWEN_Crypt_PaddAlgoId_toString(aid));
00874 return GWEN_ERROR_GENERIC;
00875 }
00876
00877 return rv;
00878 }
00879
00880
00881
00882
00883
00884