头文件:
#ifndef _UPKI__UPKI_PKCS1_PAD_H
#define _UPKI__UPKI_PKCS1_PAD_H
#include <string.h>
#include <stdlib.h>
/* suggested int types */
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
/* boolean type */
typedef enum { False, True } Boolean;
enum UPKIErrStatus {
/** Requested operation completed successfully */
UPKI_SUCCESS = 0, /* not necessary to force value to zero, but just to be safe */
/** Message is too long for this function */
UPKI_ERR_MSG_TOO_LONG,
};
#define MemCpy(s1,s2,n) memcpy((s1),(s2),(n))
#define MemSet(s1,c,n) memset((s1),(c),(n))
#define MemCmp(s1,s2,n) memcmp((s1),(s2),(n))
UPKIErrStatus UPKI_EMSA_PKCS1_v1_5_Encode(int modulusSize, uint8_t * data
);
uint8_t *UPKI_EMSA_PKCS1_v1_5_Decode(int modulusSize, uint8_t * data
);
#endif /* _UPKI__UPKI_PKCS1_PAD_H */
c文件
#include "upki_pkcs1_pad.h"
const uint8_t SHA1DigestInfo[] = {
/* SEQUENCE */
0x30,
/* length */
0x21,
/* Algorithm Identifier */
/* SEQUENCE */
0x30,
/* length */
#ifdef PKCS1_v2_1_BUG
0x1f,
#else
0x09,
#endif
/* OBJECT IDENTIFIER */
0x06,
/* Length */
0x05,
/* id-SHA1 ::= { iso(1) identified-organisation(3) oiw(14) secsig(3)
* algorithms(2) 26 */
0x2b, 0x0e, 0x03, 0x02, 0x1a,
/* NULL */
0x05, 0x00, /* NB: Oscar omits this parameter */
/* OCTET STRING */
0x04,
/* length */
0x14
};
#define SHA1DigestInfoLen sizeof(SHA1DigestInfo)
#define PKCS1_5_TYPE_01 0x01
#define PKCS1_5_TYPE_02 0x02
/** Encode a message using the EMSA-PKCS-v1_5-Encode method
*
* @ingroup upki_provider
*
* @param emLen Size of the modulus being used for the padding
* @param data Buffer to place padded message in
* @param alg Digest algorithm being used in this padding- just use sha1
*
* @pre The message to be encoded is already at
* data[emLen - messageLength - 1]
*/
UPKIErrStatus
UPKI_EMSA_PKCS1_v1_5_Encode(int emLen, uint8_t * data)
{
int startM;
const uint8_t *digestInfo;
int digestInfoLen;
/* EM = 01 || PS || 00 || T, where PS = >8 0xff bytes
*/
digestInfo = SHA1DigestInfo;
/* FIXME: Magic numbers */
startM = emLen - (20 + SHA1DigestInfoLen);
digestInfoLen = SHA1DigestInfoLen;
/* Check message length */
if (startM < 10) {
return UPKI_ERR_MSG_TOO_LONG;
}
/* 01 */
data[0] = PKCS1_5_TYPE_01;
/* PS */
MemSet(data + 1, 0xff, startM - 2);
/* 00 */
data[startM - 1] = 0;
/* DigestInfo */
MemCpy(data + startM, digestInfo, digestInfoLen);
/* M is already in there */
return UPKI_SUCCESS;
}
/** Decode a message using the EME-PKCS-v1_5-Decode method
*
* @ingroup upki_provider
*
* @param emLen Size of the modulus being used for the padding
* @param data Buffer containing the padded message
* @param alg Digest algorithm being used in this padding- just use sha1
*
* @return offset of the message or NULL on error
*
* @pre The message to be encoded is already at
* data[emLen - digestSize - 1]
*/
uint8_t *UPKI_EMSA_PKCS1_v1_5_Decode
(int emLen, uint8_t * data) {
const uint8_t *digestInfo;
int i;
int startM;
int digestInfoLen;
/* EM = 01 || PS || 00 || T, where PS = >8 0xff bytes
*/
digestInfo = SHA1DigestInfo;
/* FIXME: Magic numbers */
startM = emLen - (20 + SHA1DigestInfoLen);
digestInfoLen = SHA1DigestInfoLen;
/* Check type */
if (data[0] != PKCS1_5_TYPE_01) {
return 0;
}
/* Check FF */
for (i = 1; i < startM - 1; i++) {
if (data[i] != 0xff) {
return 0;
}
}
/* Check 0 */
if (data[i] != 0) {
return 0;
}
/* Check digest info */
if (MemCmp(data + startM, digestInfo, digestInfoLen) != 0) {
return 0;
}
/* All hunky dory, return offset */
return data + startM + digestInfoLen;
}
测试代码
#include<stdio.h>
#include "upki_pkcs1_pad.h"
const uint8_t testSHA1[] =
{
0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e,
0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d
};
/* Digest algorithm sizes */
enum DigestAlgorithmSize
{
ALG_SHA1_DIGEST_SIZE = 20,
ALG_MD5_DIGEST_SIZE = 16,
ALG_MD2_DIGEST_SIZE = 16
};
int main()
{
uint8_t buf[128];
uint8_t *data;
int errs = 0;
printf("EMSA-PKCS1-v1_5-Encode with SHA-1/n");
memcpy(buf + 127 - ALG_SHA1_DIGEST_SIZE, testSHA1, ALG_SHA1_DIGEST_SIZE);
if (UPKI_EMSA_PKCS1_v1_5_Encode(127, buf) != UPKI_SUCCESS)
{
printf("failed/n");
} else
{
printf("ok/n");
}
printf("EMSA-PKCS1-v1_5-Decode with SHA-1/n");
data = UPKI_EMSA_PKCS1_v1_5_Decode(127, buf);
if (!data || memcmp(data, testSHA1, ALG_SHA1_DIGEST_SIZE) != 0)
{
printf("failed/n");
errs++;
} else
{
printf("ok/n");
}
while(1);
return 0;
}