int EBC_Provider_EuSign_A005(AB_PROVIDER *pro, AB_USER *u, const char *requestType, const uint8_t *pMsg, uint32_t lMsg, GWEN_BUFFER *sbuf) { EBC_PROVIDER *dp; GWEN_BUFFER *xbuf; GWEN_BUFFER *hbuf; GWEN_CRYPT_TOKEN *ct; const GWEN_CRYPT_TOKEN_CONTEXT *ctx; const GWEN_CRYPT_TOKEN_KEYINFO *ki; uint32_t keyId; int ksize; uint32_t l; GWEN_CRYPT_PADDALGO *algo; int rv; int numPaddBytes=0; const uint8_t digestInfo[]= { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 }; assert(pro); dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro); assert(dp); /* get crypt token and context */ rv=EBC_Provider_MountToken(pro, u, &ct, &ctx); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); return rv; } /* get key id */ keyId=GWEN_Crypt_Token_Context_GetSignKeyId(ctx); ki=GWEN_Crypt_Token_GetKeyInfo(ct, keyId, 0xffffffff, 0); if (ki==NULL) { DBG_INFO(AQEBICS_LOGDOMAIN, "Keyinfo %04x not found on crypt token [%s:%s]", keyId, GWEN_Crypt_Token_GetTypeName(ct), GWEN_Crypt_Token_GetTokenName(ct)); GWEN_Crypt_Token_Close(ct, 0, 0); return GWEN_ERROR_NOT_FOUND; } xbuf=GWEN_Buffer_new(0, 40, 0, 1); EBC_Provider_Sha256(pMsg, lMsg, xbuf); /* add digestInfo to hash of SignedInfo */ hbuf=GWEN_Buffer_new(0, 256, 0, 1); ksize=GWEN_Crypt_Token_KeyInfo_GetKeySize(ki); GWEN_Buffer_AppendByte(hbuf, 0x01); /* block type */ numPaddBytes=ksize-3-sizeof(digestInfo)-GWEN_Buffer_GetUsedBytes(xbuf); if (numPaddBytes<1) { DBG_ERROR(AQEBICS_LOGDOMAIN, "Invalid number of padd bytes, key too small (%d)", numPaddBytes); GWEN_Buffer_free(xbuf); GWEN_Buffer_free(hbuf); return GWEN_ERROR_INTERNAL; } GWEN_Buffer_FillWithBytes(hbuf, 0xff, numPaddBytes); GWEN_Buffer_AppendByte(hbuf, 0x01); /* separator */ GWEN_Buffer_AppendBytes(hbuf, (const char *)digestInfo, sizeof(digestInfo)); /* digest info */ GWEN_Buffer_AppendBytes(hbuf, GWEN_Buffer_GetStart(xbuf), GWEN_Buffer_GetUsedBytes(xbuf)); /* hash */ GWEN_Buffer_free(xbuf); /* select padd algo */ algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_None); GWEN_Crypt_PaddAlgo_SetPaddSize(algo, ksize); /* actually sign */ GWEN_Buffer_AllocRoom(sbuf, ksize+16); l=GWEN_Buffer_GetMaxUnsegmentedWrite(sbuf); rv=GWEN_Crypt_Token_Sign(ct, keyId, algo, (const uint8_t *)GWEN_Buffer_GetStart(hbuf), GWEN_Buffer_GetUsedBytes(hbuf), (uint8_t *)GWEN_Buffer_GetPosPointer(sbuf), &l, NULL, /* ignore seq counter */ 0); GWEN_Crypt_PaddAlgo_free(algo); if (rv<0) { DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv); GWEN_Buffer_free(hbuf); return rv; } GWEN_Buffer_IncrementPos(sbuf, l); GWEN_Buffer_AdjustUsedBytes(sbuf); GWEN_Buffer_free(hbuf); return 0; }
int GWEN_Padd_ApplyPaddAlgo(const GWEN_CRYPT_PADDALGO *a, GWEN_BUFFER *buf) { int rv; unsigned int diff; unsigned int bsize; unsigned int dstSize; unsigned int chunkSize; GWEN_CRYPT_PADDALGOID aid; assert(a); assert(buf); aid=GWEN_Crypt_PaddAlgo_GetId(a); if (aid==GWEN_Crypt_PaddAlgoId_None) /* short return if there is no padding to be done */ return 0; chunkSize=GWEN_Crypt_PaddAlgo_GetPaddSize(a); if (chunkSize==0) { DBG_ERROR(GWEN_LOGDOMAIN, "Invalid chunk size (0)"); return GWEN_ERROR_INVALID; } bsize=GWEN_Buffer_GetUsedBytes(buf); dstSize=bsize+(chunkSize-1); dstSize=(dstSize/chunkSize)*chunkSize; diff=dstSize-bsize; DBG_INFO(GWEN_LOGDOMAIN, "Padding with algo \"%s\"", GWEN_Crypt_PaddAlgoId_toString(aid)); switch(aid) { case GWEN_Crypt_PaddAlgoId_None: rv=0; break; case GWEN_Crypt_PaddAlgoId_Iso9796_1A4: if (dstSize>96) { DBG_ERROR(GWEN_LOGDOMAIN, "Padding size must be <=96 bytes (is %d)", dstSize); return GWEN_ERROR_INVALID; } rv=GWEN_Padd_PaddWithISO9796(buf); break; case GWEN_Crypt_PaddAlgoId_Pkcs1_1: rv=GWEN_Padd_PaddWithPkcs1Bt1(buf, dstSize); break; case GWEN_Crypt_PaddAlgoId_Pkcs1_2: rv=GWEN_Padd_PaddWithPkcs1Bt2(buf, dstSize); break; case GWEN_Crypt_PaddAlgoId_LeftZero: rv=GWEN_Buffer_FillLeftWithBytes(buf, 0, diff); break; case GWEN_Crypt_PaddAlgoId_RightZero: rv=GWEN_Buffer_FillWithBytes(buf, 0, diff); break; case GWEN_Crypt_PaddAlgoId_AnsiX9_23: return GWEN_Padd_PaddWithAnsiX9_23(buf); case GWEN_Crypt_PaddAlgoId_Iso9796_2: return GWEN_Padd_PaddWithIso9796_2(buf, dstSize); case GWEN_Crypt_PaddAlgoId_Iso9796_1: default: DBG_INFO(GWEN_LOGDOMAIN, "Algo-Type %d (%s) not supported", aid, GWEN_Crypt_PaddAlgoId_toString(aid)); return GWEN_ERROR_NOT_AVAILABLE; } if (rv) { DBG_ERROR(GWEN_LOGDOMAIN, "Error padding with algo %d (%s)", aid, GWEN_Crypt_PaddAlgoId_toString(aid)); return GWEN_ERROR_GENERIC; } return rv; }