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
00027
00028
00029 #ifdef HAVE_CONFIG_H
00030 # include <config.h>
00031 #endif
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_23(GWEN_BUFFER *src) {
00228 unsigned char paddLength;
00229 unsigned int i;
00230
00231 paddLength=8-(GWEN_Buffer_GetUsedBytes(src) % 8);
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_23(GWEN_BUFFER *src) {
00240 const char *p;
00241 unsigned int lastpos;
00242 unsigned char paddLength;
00243
00244 lastpos=GWEN_Buffer_GetUsedBytes(src);
00245 if (lastpos<8) {
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>8) {
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_PaddWithPkcs1Bt1(GWEN_BUFFER *buf, int dstSize){
00265 unsigned int diff;
00266 char *p;
00267
00268 if ((unsigned int)dstSize<GWEN_Buffer_GetUsedBytes(buf)) {
00269 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer contains too much data");
00270 return GWEN_ERROR_INVALID;
00271 }
00272 diff=dstSize-GWEN_Buffer_GetUsedBytes(buf);
00273 if (diff<11) {
00274
00275
00276 DBG_ERROR(GWEN_LOGDOMAIN,
00277 "Buffer contains too many bytes (diff is <11)");
00278 return GWEN_ERROR_INVALID;
00279 }
00280
00281
00282 GWEN_Buffer_Rewind(buf);
00283 if (GWEN_Buffer_InsertRoom(buf, diff)) {
00284 DBG_ERROR(GWEN_LOGDOMAIN, "Could not insert room for %d bytes", diff);
00285 return GWEN_ERROR_GENERIC;
00286 }
00287
00288 p=GWEN_Buffer_GetStart(buf);
00289 *(p++)=0x00;
00290 *(p++)=0x01;
00291 if (diff>3) {
00292 memset(p, 0xff, diff-3);
00293 p+=diff-3;
00294 }
00295 *(p++)=0x00;
00296
00297 return 0;
00298 }
00299
00300
00301
00302 int GWEN_Padd_PaddWithPkcs1Bt2(GWEN_BUFFER *buf, int dstSize){
00303 unsigned int diff;
00304 char *p;
00305 int i;
00306
00307 if ((unsigned int)dstSize<GWEN_Buffer_GetUsedBytes(buf)) {
00308 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer contains too much data");
00309 return GWEN_ERROR_INVALID;
00310 }
00311 diff=dstSize-GWEN_Buffer_GetUsedBytes(buf);
00312 if (diff<11) {
00313
00314
00315 DBG_ERROR(GWEN_LOGDOMAIN,
00316 "Buffer contains too many bytes (diff is <11)");
00317 return GWEN_ERROR_INVALID;
00318 }
00319
00320
00321 GWEN_Buffer_Rewind(buf);
00322 if (GWEN_Buffer_InsertRoom(buf, diff)) {
00323 DBG_ERROR(GWEN_LOGDOMAIN, "Could not insert room for %d bytes", diff);
00324 return GWEN_ERROR_GENERIC;
00325 }
00326
00327 p=GWEN_Buffer_GetStart(buf);
00328 *(p++)=0x00;
00329 *(p++)=0x02;
00330 GWEN_Crypt_Random(2, (uint8_t*)p, diff-3);
00331 for (i=0; i<diff-3; i++) {
00332 if (*p==0)
00333
00334 *p=0xff;
00335 p++;
00336 }
00337 *(p++)=0x00;
00338
00339 return 0;
00340 }
00341
00342
00343
00344 int GWEN_Padd__UnpaddWithPkcs1Bt1Or2(GWEN_BUFFER *buf) {
00345 char *p;
00346 uint32_t len;
00347 uint32_t paddBytes;
00348
00349 assert(buf);
00350 len=GWEN_Buffer_GetUsedBytes(buf);
00351 assert(len);
00352
00353 p=GWEN_Buffer_GetStart(buf);
00354 if (*p==0) {
00355 p++;
00356 len--;
00357 }
00358 if (len<11) {
00359 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes left (%d)", len);
00360 return GWEN_ERROR_INVALID;
00361 }
00362
00363 if (*p!=0x01 && *p!=0x02) {
00364 DBG_ERROR(GWEN_LOGDOMAIN, "Unsupported block type %02x", *p);
00365 return GWEN_ERROR_INVALID;
00366 }
00367 p++; len--;
00368
00369
00370 paddBytes=0;
00371 while(*p!=0x00 && len) {
00372 p++; len--;
00373 paddBytes++;
00374 }
00375
00376 if (*p!=0x00) {
00377 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding");
00378 return GWEN_ERROR_INVALID;
00379 }
00380 p++; len--;
00381
00382 if (paddBytes<8) {
00383
00384 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding (too few padding bytes)");
00385 return GWEN_ERROR_INVALID;
00386 }
00387
00388 GWEN_Buffer_Crop(buf, GWEN_Buffer_GetUsedBytes(buf)-len, len);
00389
00390 return 0;
00391 }
00392
00393
00394
00395 int GWEN_Padd_UnpaddWithPkcs1Bt1(GWEN_BUFFER *src){
00396 return GWEN_Padd__UnpaddWithPkcs1Bt1Or2(src);
00397 }
00398
00399
00400
00401 int GWEN_Padd_UnpaddWithPkcs1Bt2(GWEN_BUFFER *src){
00402 return GWEN_Padd__UnpaddWithPkcs1Bt1Or2(src);
00403 }
00404
00405
00406
00407 int GWEN_Padd_MGF1(uint8_t *pDestBuffer,
00408 uint32_t lDestBuffer,
00409 const uint8_t *pSeed,
00410 uint32_t lSeed,
00411 GWEN_MDIGEST *md) {
00412 uint32_t bytesLeft=lDestBuffer;
00413 uint32_t i;
00414 uint8_t counter[4];
00415 uint8_t *p;
00416
00417 p=pDestBuffer;
00418
00419 for (i=0; bytesLeft>0; i++) {
00420 int rv;
00421 uint32_t l;
00422
00423 counter[0]= (uint8_t)((i>>24) & 0xff);
00424 counter[1]= (uint8_t)((i>>16) & 0xff);
00425 counter[2]= (uint8_t)((i>>8) & 0xff);
00426 counter[3]= (uint8_t)(i & 0xff);
00427
00428 rv=GWEN_MDigest_Begin(md);
00429 if (rv<0) {
00430 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00431 return rv;
00432 }
00433
00434 rv=GWEN_MDigest_Update(md, pSeed, lSeed);
00435 if (rv<0) {
00436 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00437 return rv;
00438 }
00439
00440 rv=GWEN_MDigest_Update(md, counter, 4);
00441 if (rv<0) {
00442 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00443 return rv;
00444 }
00445
00446 rv=GWEN_MDigest_End(md);
00447 if (rv<0) {
00448 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00449 return rv;
00450 }
00451
00452 l=GWEN_MDigest_GetDigestSize(md);
00453 if (bytesLeft<l)
00454 l=bytesLeft;
00455 memmove(p, GWEN_MDigest_GetDigestPtr(md), l);
00456 bytesLeft-=l;
00457 p+=l;
00458 }
00459
00460 return 0;
00461 }
00462
00463
00464
00465 int GWEN_Padd_AddPkcs1Pss(uint8_t *pDestBuffer,
00466 uint32_t lDestBuffer,
00467 uint32_t nbits,
00468 const uint8_t *pHash,
00469 uint32_t lHash,
00470 uint32_t lSalt,
00471 GWEN_MDIGEST *md) {
00472 uint32_t emLen;
00473 uint8_t *pSalt=NULL;
00474 uint8_t *pDB;
00475 uint8_t *pDbMask;
00476 uint32_t x;
00477 uint32_t i;
00478 uint8_t *p;
00479 int rv;
00480 uint8_t hashMBar[64];
00481 int numberOfBitsInByte0;
00482
00483 emLen=nbits/8;
00484 if (nbits%8)
00485 emLen++;
00486
00487
00488 numberOfBitsInByte0=((nbits-1) & 0x07);
00489 if (numberOfBitsInByte0==0) {
00490 *(pDestBuffer++)=0;
00491 emLen--;
00492 }
00493
00494
00495 pSalt=(uint8_t*) malloc(lSalt);
00496 assert(pSalt);
00497 GWEN_Crypt_Random(2, pSalt, lSalt);
00498
00499
00500 rv=GWEN_MDigest_Begin(md);
00501 if (rv<0) {
00502 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00503 free(pSalt);
00504 return rv;
00505 }
00506
00507 rv=GWEN_MDigest_Update(md, nullarray, 8);
00508 if (rv<0) {
00509 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00510 free(pSalt);
00511 return rv;
00512 }
00513
00514 rv=GWEN_MDigest_Update(md, pHash, lHash);
00515 if (rv<0) {
00516 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00517 free(pSalt);
00518 return rv;
00519 }
00520
00521 rv=GWEN_MDigest_Update(md, pSalt, lSalt);
00522 if (rv<0) {
00523 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00524 free(pSalt);
00525 return rv;
00526 }
00527
00528 rv=GWEN_MDigest_End(md);
00529 if (rv<0) {
00530 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00531 free(pSalt);
00532 return rv;
00533 }
00534
00535 memmove(hashMBar,
00536 GWEN_MDigest_GetDigestPtr(md),
00537 GWEN_MDigest_GetDigestSize(md));
00538
00539
00540 x=emLen-GWEN_MDigest_GetDigestSize(md)-lSalt-2;
00541 pDB=(uint8_t*)malloc(emLen);
00542 assert(pDB);
00543 p=pDB;
00544 memset(p, 0, x);
00545 p+=x;
00546 *(p++)=0x01;
00547 memmove(p, pSalt, lSalt);
00548 p+=lSalt;
00549
00550
00551 x=emLen-GWEN_MDigest_GetDigestSize(md)-1;
00552 pDbMask=(uint8_t*)malloc(x);
00553 rv=GWEN_Padd_MGF1(pDbMask, x,
00554 hashMBar, GWEN_MDigest_GetDigestSize(md),
00555 md);
00556 if (rv<0) {
00557 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00558 free(pDbMask);
00559 free(pDB);
00560 free(pSalt);
00561 return rv;
00562 }
00563
00564
00565 p=pDestBuffer;
00566 for (i=0; i<x; i++)
00567 *(p++)=pDB[i] ^ pDbMask[i];
00568
00569
00570 memmove(p, hashMBar, GWEN_MDigest_GetDigestSize(md));
00571 p+=GWEN_MDigest_GetDigestSize(md);
00572
00573 *(p++)=0xbc;
00574
00575
00576 if (numberOfBitsInByte0)
00577 pDestBuffer[0] &= 0xff >> (8-numberOfBitsInByte0);
00578
00579 free(pDbMask);
00580 free(pDB);
00581 free(pSalt);
00582
00583 return emLen;
00584 }
00585
00586
00587
00588 int GWEN_Padd_VerifyPkcs1Pss(const uint8_t *pSrcBuffer,
00589 uint32_t lSrcBuffer,
00590 uint32_t nbits,
00591 const uint8_t *pHash,
00592 uint32_t lHash,
00593 uint32_t lSalt,
00594 GWEN_MDIGEST *md) {
00595 uint32_t emLen;
00596 const uint8_t *pSalt;
00597 uint8_t *pDB;
00598 uint32_t x;
00599 uint32_t i;
00600 int rv;
00601 const uint8_t *hashMBar;
00602 int numberOfBitsInByte0;
00603
00604 emLen=nbits/8;
00605 if (nbits%8)
00606 emLen++;
00607
00608
00609 numberOfBitsInByte0=((nbits-1) & 0x07);
00610
00611 if (numberOfBitsInByte0==0) {
00612 pSrcBuffer++;
00613 emLen--;
00614 }
00615 else {
00616 if (pSrcBuffer[0] & (0xff << numberOfBitsInByte0)) {
00617 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding: leading bits must be zero (%d)", numberOfBitsInByte0);
00618 return GWEN_ERROR_BAD_DATA;
00619 }
00620 }
00621
00622
00623 if (emLen < (GWEN_MDigest_GetDigestSize(md)+lSalt+2)) {
00624 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding: Key too small for data");
00625 return GWEN_ERROR_BAD_DATA;
00626 }
00627
00628
00629 if (lSrcBuffer < emLen) {
00630 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding: Provided data too small (is %d, expected %d)",
00631 lSrcBuffer, emLen);
00632 return GWEN_ERROR_BAD_DATA;
00633 }
00634
00635
00636 x=emLen-GWEN_MDigest_GetDigestSize(md)-1;
00637
00638 pDB=(uint8_t*)malloc(x);
00639 hashMBar=pSrcBuffer+x;
00640 rv=GWEN_Padd_MGF1(pDB, x,
00641 hashMBar, GWEN_MDigest_GetDigestSize(md),
00642 md);
00643 if (rv<0) {
00644 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00645 free(pDB);
00646 return rv;
00647 }
00648
00649
00650 for (i=0; i<x; i++)
00651 pDB[i] ^= pSrcBuffer[i];
00652
00653
00654 if (numberOfBitsInByte0)
00655 pDB[0] &= (0xff >> (8-numberOfBitsInByte0));
00656
00657
00658
00659
00660 for (i=0; (i<(x-1) && pDB[i]==0); i++);
00661
00662 if (pDB[i]!=0x01) {
00663 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding: byte 0x01 missing before salt");
00664 free(pDB);
00665 return GWEN_ERROR_BAD_DATA;
00666 }
00667 i++;
00668
00669
00670 if ((x-i)!=lSalt) {
00671 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding: bad length for salt (is %d, should be %d)",
00672 x-i, lSalt);
00673 free(pDB);
00674 return GWEN_ERROR_BAD_DATA;
00675 }
00676
00677
00678 pSalt=pDB+i;
00679
00680
00681 rv=GWEN_MDigest_Begin(md);
00682 if (rv<0) {
00683 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00684 free(pDB);
00685 return rv;
00686 }
00687
00688 rv=GWEN_MDigest_Update(md, nullarray, 8);
00689 if (rv<0) {
00690 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00691 free(pDB);
00692 return rv;
00693 }
00694
00695 if (lHash) {
00696 rv=GWEN_MDigest_Update(md, pHash, lHash);
00697 if (rv<0) {
00698 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00699 free(pDB);
00700 return rv;
00701 }
00702 }
00703
00704 rv=GWEN_MDigest_Update(md, pSalt, lSalt);
00705 if (rv<0) {
00706 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00707 free(pDB);
00708 return rv;
00709 }
00710
00711 rv=GWEN_MDigest_End(md);
00712 if (rv<0) {
00713 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00714 free(pDB);
00715 return rv;
00716 }
00717 if (memcmp(hashMBar,
00718 GWEN_MDigest_GetDigestPtr(md),
00719 GWEN_MDigest_GetDigestSize(md))!=0) {
00720 DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding: hash does not match");
00721
00722 free(pDB);
00723 return GWEN_ERROR_VERIFY;
00724 }
00725
00726 free(pDB);
00727
00728 DBG_INFO(GWEN_LOGDOMAIN, "Hash ok.");
00729 return 0;
00730 }
00731
00732
00733
00734 int GWEN_Padd_ApplyPaddAlgo(const GWEN_CRYPT_PADDALGO *a, GWEN_BUFFER *buf) {
00735 int rv;
00736 unsigned int diff;
00737 unsigned int bsize;
00738 unsigned int dstSize;
00739 unsigned int chunkSize;
00740 GWEN_CRYPT_PADDALGOID aid;
00741
00742 assert(a);
00743 assert(buf);
00744
00745 aid=GWEN_Crypt_PaddAlgo_GetId(a);
00746 if (aid==GWEN_Crypt_PaddAlgoId_None)
00747
00748 return 0;
00749
00750 chunkSize=GWEN_Crypt_PaddAlgo_GetPaddSize(a);
00751 if (chunkSize==0) {
00752 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid chunk size (0)");
00753 return GWEN_ERROR_INVALID;
00754 }
00755
00756 bsize=GWEN_Buffer_GetUsedBytes(buf);
00757 dstSize=bsize+(chunkSize-1);
00758 dstSize=(dstSize/chunkSize)*chunkSize;
00759 diff=dstSize-bsize;
00760
00761 DBG_INFO(GWEN_LOGDOMAIN, "Padding with algo \"%s\"",
00762 GWEN_Crypt_PaddAlgoId_toString(aid));
00763
00764 switch(aid) {
00765 case GWEN_Crypt_PaddAlgoId_None:
00766 rv=0;
00767 break;
00768
00769 case GWEN_Crypt_PaddAlgoId_Iso9796_1A4:
00770 if (dstSize>96) {
00771 DBG_ERROR(GWEN_LOGDOMAIN,
00772 "Padding size must be <=96 bytes (is %d)",
00773 dstSize);
00774 return GWEN_ERROR_INVALID;
00775 }
00776 rv=GWEN_Padd_PaddWithISO9796(buf);
00777 break;
00778
00779 case GWEN_Crypt_PaddAlgoId_Pkcs1_1:
00780 rv=GWEN_Padd_PaddWithPkcs1Bt1(buf, dstSize);
00781 break;
00782
00783 case GWEN_Crypt_PaddAlgoId_Pkcs1_2:
00784 rv=GWEN_Padd_PaddWithPkcs1Bt2(buf, dstSize);
00785 break;
00786
00787 case GWEN_Crypt_PaddAlgoId_LeftZero:
00788 rv=GWEN_Buffer_FillLeftWithBytes(buf, 0, diff);
00789 break;
00790
00791 case GWEN_Crypt_PaddAlgoId_RightZero:
00792 rv=GWEN_Buffer_FillWithBytes(buf, 0, diff);
00793 break;
00794
00795 case GWEN_Crypt_PaddAlgoId_AnsiX9_23:
00796 return GWEN_Padd_PaddWithAnsiX9_23(buf);
00797
00798 case GWEN_Crypt_PaddAlgoId_Iso9796_2:
00799 return GWEN_Padd_PaddWithIso9796_2(buf, dstSize);
00800
00801 case GWEN_Crypt_PaddAlgoId_Iso9796_1:
00802 default:
00803 DBG_INFO(GWEN_LOGDOMAIN, "Algo-Type %d (%s) not supported",
00804 aid, GWEN_Crypt_PaddAlgoId_toString(aid));
00805 return GWEN_ERROR_NOT_AVAILABLE;
00806 }
00807
00808 if (rv) {
00809 DBG_ERROR(GWEN_LOGDOMAIN, "Error padding with algo %d (%s)",
00810 aid, GWEN_Crypt_PaddAlgoId_toString(aid));
00811 return GWEN_ERROR_GENERIC;
00812 }
00813
00814 return rv;
00815 }
00816
00817
00818
00819 int GWEN_Padd_UnapplyPaddAlgo(const GWEN_CRYPT_PADDALGO *a, GWEN_BUFFER *buf){
00820 int rv;
00821 GWEN_CRYPT_PADDALGOID aid;
00822
00823 assert(a);
00824 assert(buf);
00825
00826 aid=GWEN_Crypt_PaddAlgo_GetId(a);
00827 DBG_INFO(GWEN_LOGDOMAIN, "Unpadding with algo \"%s\"",
00828 GWEN_Crypt_PaddAlgoId_toString(aid));
00829
00830 switch(aid) {
00831 case GWEN_Crypt_PaddAlgoId_None:
00832 rv=0;
00833 break;
00834
00835 case GWEN_Crypt_PaddAlgoId_Pkcs1_1:
00836 rv=GWEN_Padd_UnpaddWithPkcs1Bt1(buf);
00837 break;
00838
00839 case GWEN_Crypt_PaddAlgoId_Pkcs1_2:
00840 rv=GWEN_Padd_UnpaddWithPkcs1Bt2(buf);
00841 break;
00842
00843 case GWEN_Crypt_PaddAlgoId_AnsiX9_23:
00844 return GWEN_Padd_UnpaddWithAnsiX9_23(buf);
00845
00846 case GWEN_Crypt_PaddAlgoId_Iso9796_2:
00847 return GWEN_Padd_UnpaddWithIso9796_2(buf);
00848
00849 case GWEN_Crypt_PaddAlgoId_Iso9796_1:
00850 case GWEN_Crypt_PaddAlgoId_LeftZero:
00851 case GWEN_Crypt_PaddAlgoId_RightZero:
00852 case GWEN_Crypt_PaddAlgoId_Iso9796_1A4:
00853 default:
00854 DBG_INFO(GWEN_LOGDOMAIN, "Algo-Type %d (%s) not supported",
00855 aid, GWEN_Crypt_PaddAlgoId_toString(aid));
00856 return GWEN_ERROR_NOT_AVAILABLE;
00857 }
00858
00859 if (rv) {
00860 DBG_ERROR(GWEN_LOGDOMAIN, "Error padding with algo %d (%s)",
00861 aid, GWEN_Crypt_PaddAlgoId_toString(aid));
00862 return GWEN_ERROR_GENERIC;
00863 }
00864
00865 return rv;
00866 }
00867
00868
00869
00870
00871
00872