implement support for SHA2 (still experimental)
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3115 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
1b4472ca9f
commit
a2f622a215
|
@ -783,11 +783,16 @@ cardos_compute_signature(sc_card_t *card, const u8 *data, size_t datalen,
|
|||
/* remove padding: first try pkcs1 bt01 padding */
|
||||
r = sc_pkcs1_strip_01_padding(data, datalen, buf, &tmp_len);
|
||||
if (r != SC_SUCCESS) {
|
||||
/* no pkcs1 bt01 padding => let's try zero padding */
|
||||
const u8 *p = data;
|
||||
/* no pkcs1 bt01 padding => let's try zero padding
|
||||
* This can only work if the data tbs doesn't have a
|
||||
* leading 0 byte. */
|
||||
tmp_len = buf_len;
|
||||
r = sc_strip_zero_padding(data, datalen, buf, &tmp_len);
|
||||
if (r != SC_SUCCESS)
|
||||
SC_FUNC_RETURN(ctx, 4, r);
|
||||
while (*p == 0 && tmp_len != 0) {
|
||||
++p;
|
||||
--tmp_len;
|
||||
}
|
||||
memcpy(buf, p, tmp_len);
|
||||
}
|
||||
sc_ctx_suppress_errors_on(ctx);
|
||||
r = do_compute_signature(card, buf, tmp_len, out, outlen);
|
||||
|
|
|
@ -568,11 +568,16 @@ incrypto34_compute_signature(sc_card_t *card, const u8 *data, size_t datalen,
|
|||
/* remove padding: first try pkcs1 bt01 padding */
|
||||
r = sc_pkcs1_strip_01_padding(data, datalen, buf, &tmp_len);
|
||||
if (r != SC_SUCCESS) {
|
||||
/* no pkcs1 bt01 padding => let's try zero padding */
|
||||
const u8 *p = data;
|
||||
/* no pkcs1 bt01 padding => let's try zero padding.
|
||||
* This can only work if the data tbs doesn't have a
|
||||
* leading 0 byte. */
|
||||
tmp_len = buf_len;
|
||||
r = sc_strip_zero_padding(data, datalen, buf, &tmp_len);
|
||||
if (r != SC_SUCCESS)
|
||||
SC_FUNC_RETURN(ctx, 4, r);
|
||||
while (*p == 0 && tmp_len != 0) {
|
||||
++p;
|
||||
--tmp_len;
|
||||
}
|
||||
memcpy(buf, p, tmp_len);
|
||||
}
|
||||
sc_ctx_suppress_errors_on(ctx);
|
||||
r = do_compute_signature(card, buf, tmp_len, out, outlen);
|
||||
|
|
|
@ -123,19 +123,38 @@ int sc_asn1_read_tag(const u8 ** buf, size_t buflen, unsigned int *cla_out,
|
|||
/* pkcs1 padding/encoding functions */
|
||||
/********************************************************************/
|
||||
|
||||
int sc_pkcs1_add_01_padding(const u8 *in, size_t in_len, u8 *out,
|
||||
size_t *out_len, size_t mod_length);
|
||||
int sc_pkcs1_strip_01_padding(const u8 *in_dat, size_t in_len, u8 *out_dat,
|
||||
size_t *out_len);
|
||||
int sc_pkcs1_strip_02_padding(const u8 *data, size_t len, u8 *out_dat,
|
||||
size_t *out_len);
|
||||
int sc_pkcs1_add_digest_info_prefix(unsigned int algorithm, const u8 *in_dat,
|
||||
size_t in_len, u8 *out_dat, size_t *out_len);
|
||||
int sc_pkcs1_strip_digest_info_prefix(unsigned int *algorithm,
|
||||
const u8 *in_dat, size_t in_len, u8 *out_dat, size_t *out_len);
|
||||
|
||||
/**
|
||||
* PKCS1 encodes the given data.
|
||||
* @param ctx IN sc_context_t object
|
||||
* @param flags IN the algorithm to use
|
||||
* @param in IN input buffer
|
||||
* @param inlen IN length of the input
|
||||
* @param out OUT output buffer (in == out is allowed)
|
||||
* @param outlen OUT length of the output buffer
|
||||
* @param modlen IN length of the modulus in bytes
|
||||
* @return SC_SUCCESS on success and an error code otherwise
|
||||
*/
|
||||
int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags,
|
||||
const u8 *in, size_t in_len, u8 *out, size_t *out_len, size_t mod_len);
|
||||
int sc_strip_zero_padding(const u8 *in,size_t in_len, u8 *out, size_t *out_len);
|
||||
const u8 *in, size_t inlen, u8 *out, size_t *outlen, size_t modlen);
|
||||
/**
|
||||
* Get the necessary padding and sec. env. flags.
|
||||
* @param ctx IN sc_contex_t object
|
||||
* @param iflags IN the desired algorithms flags
|
||||
* @param caps IN the card / key capabilities
|
||||
* @param pflags OUT the padding flags to use
|
||||
* @param salg OUT the security env. algorithm flag to use
|
||||
* @return SC_SUCCESS on success and an error code otherwise
|
||||
*/
|
||||
int sc_get_encoding_flags(sc_context_t *ctx,
|
||||
unsigned long iflags, unsigned long caps,
|
||||
unsigned long *pflags, unsigned long *salg);
|
||||
|
||||
/********************************************************************/
|
||||
/* mutex functions */
|
||||
|
|
|
@ -181,11 +181,15 @@ extern "C" {
|
|||
/* If the card is willing to produce a cryptogram with the following
|
||||
* hash values, set these flags accordingly. */
|
||||
#define SC_ALGORITHM_RSA_HASH_NONE 0x00000010
|
||||
#define SC_ALGORITHM_RSA_HASHES 0x000001E0
|
||||
#define SC_ALGORITHM_RSA_HASH_SHA1 0x00000020
|
||||
#define SC_ALGORITHM_RSA_HASH_MD5 0x00000040
|
||||
#define SC_ALGORITHM_RSA_HASH_MD5_SHA1 0x00000080
|
||||
#define SC_ALGORITHM_RSA_HASH_RIPEMD160 0x00000100
|
||||
#define SC_ALGORITHM_RSA_HASH_SHA256 0x00000200
|
||||
#define SC_ALGORITHM_RSA_HASH_SHA384 0x00000400
|
||||
#define SC_ALGORITHM_RSA_HASH_SHA512 0x00000800
|
||||
#define SC_ALGORITHM_RSA_HASH_SHA224 0x00001000
|
||||
#define SC_ALGORITHM_RSA_HASHES 0x00001FE0
|
||||
|
||||
/* Event masks for sc_wait_for_event() */
|
||||
#define SC_EVENT_CARD_INSERTED 0x0001
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* sc-padding.c: miscellaneous padding functions
|
||||
* padding.c: miscellaneous padding functions
|
||||
*
|
||||
* Copyright (C) 2001, 2002 Juha Yrjölä <juha.yrjola@iki.fi>
|
||||
* Copyright (C) 2003 Nils Larsch <larsch@trustcenter.de>
|
||||
* Copyright (C) 2003 - 2007 Nils Larsch <larsch@trustcenter.de>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -22,7 +22,6 @@
|
|||
#include "internal.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* TODO doxygen comments */
|
||||
|
||||
|
@ -37,22 +36,41 @@ static const u8 hdr_sha1[] = {
|
|||
0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a,
|
||||
0x05, 0x00, 0x04, 0x14
|
||||
};
|
||||
static const u8 hdr_sha256[] = {
|
||||
0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
|
||||
0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
|
||||
};
|
||||
static const u8 hdr_sha384[] = {
|
||||
0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
|
||||
0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30
|
||||
};
|
||||
static const u8 hdr_sha512[] = {
|
||||
0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
|
||||
0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40
|
||||
};
|
||||
static const u8 hdr_sha224[] = {
|
||||
0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
|
||||
0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c
|
||||
};
|
||||
static const u8 hdr_ripemd160[] = {
|
||||
0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, 0x02, 0x01,
|
||||
0x05, 0x00, 0x04, 0x14
|
||||
};
|
||||
|
||||
|
||||
#define DIGEST_INFO_COUNT 6
|
||||
static const struct digest_info_prefix {
|
||||
unsigned int algorithm;
|
||||
const u8 * hdr;
|
||||
size_t hdr_len;
|
||||
size_t hash_len;
|
||||
} digest_info_prefix[DIGEST_INFO_COUNT] = {
|
||||
} digest_info_prefix[] = {
|
||||
{ SC_ALGORITHM_RSA_HASH_NONE, NULL, 0, 0 },
|
||||
{ SC_ALGORITHM_RSA_HASH_MD5, hdr_md5, sizeof(hdr_md5), 16 },
|
||||
{ SC_ALGORITHM_RSA_HASH_SHA1, hdr_sha1, sizeof(hdr_sha1), 20 },
|
||||
{ SC_ALGORITHM_RSA_HASH_SHA256, hdr_sha256, sizeof(hdr_sha256), 32 },
|
||||
{ SC_ALGORITHM_RSA_HASH_SHA384, hdr_sha384, sizeof(hdr_sha384), 48 },
|
||||
{ SC_ALGORITHM_RSA_HASH_SHA512, hdr_sha512, sizeof(hdr_sha512), 64 },
|
||||
{ SC_ALGORITHM_RSA_HASH_SHA224, hdr_sha224, sizeof(hdr_sha224), 28 },
|
||||
{ SC_ALGORITHM_RSA_HASH_RIPEMD160,hdr_ripemd160, sizeof(hdr_ripemd160), 20 },
|
||||
{ SC_ALGORITHM_RSA_HASH_MD5_SHA1, NULL, 0, 36 },
|
||||
{ 0, NULL, 0, 0 }
|
||||
|
@ -60,8 +78,8 @@ static const struct digest_info_prefix {
|
|||
|
||||
/* add/remove pkcs1 BT01 padding */
|
||||
|
||||
int sc_pkcs1_add_01_padding(const u8 *in, size_t in_len, u8 *out,
|
||||
size_t *out_len, size_t mod_length)
|
||||
static int sc_pkcs1_add_01_padding(const u8 *in, size_t in_len,
|
||||
u8 *out, size_t *out_len, size_t mod_length)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
|
@ -82,15 +100,15 @@ int sc_pkcs1_add_01_padding(const u8 *in, size_t in_len, u8 *out,
|
|||
return SC_SUCCESS;
|
||||
}
|
||||
|
||||
int sc_pkcs1_strip_01_padding(const u8 *in_dat, size_t in_len, u8 *out,
|
||||
size_t *out_len)
|
||||
int sc_pkcs1_strip_01_padding(const u8 *in_dat, size_t in_len,
|
||||
u8 *out, size_t *out_len)
|
||||
{
|
||||
const u8 *tmp = in_dat;
|
||||
size_t len;
|
||||
|
||||
if (in_dat == NULL || in_len < 10)
|
||||
return SC_ERROR_INTERNAL;
|
||||
/* ignore leading zero byte */
|
||||
/* skip leading zero byte */
|
||||
if (*tmp == 0) {
|
||||
tmp++;
|
||||
in_len--;
|
||||
|
@ -122,7 +140,7 @@ int sc_pkcs1_strip_02_padding(const u8 *data, size_t len, u8 *out,
|
|||
|
||||
if (data == NULL || len < 3)
|
||||
return SC_ERROR_INTERNAL;
|
||||
/* skip leading zero octet (not part of the pkcs1 BT02 padding) */
|
||||
/* skip leading zero byte */
|
||||
if (*data == 0) {
|
||||
data++;
|
||||
len--;
|
||||
|
@ -147,12 +165,12 @@ int sc_pkcs1_strip_02_padding(const u8 *data, size_t len, u8 *out,
|
|||
}
|
||||
|
||||
/* add/remove DigestInfo prefix */
|
||||
int sc_pkcs1_add_digest_info_prefix(unsigned int algorithm, const u8 *in,
|
||||
size_t in_len, u8 *out, size_t *out_len)
|
||||
static int sc_pkcs1_add_digest_info_prefix(unsigned int algorithm,
|
||||
const u8 *in, size_t in_len, u8 *out, size_t *out_len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < DIGEST_INFO_COUNT; i++) {
|
||||
for (i = 0; digest_info_prefix[i].algorithm != 0; i++) {
|
||||
if (algorithm == digest_info_prefix[i].algorithm) {
|
||||
const u8 *hdr = digest_info_prefix[i].hdr;
|
||||
size_t hdr_len = digest_info_prefix[i].hdr_len,
|
||||
|
@ -175,7 +193,7 @@ int sc_pkcs1_strip_digest_info_prefix(unsigned int *algorithm,
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < DIGEST_INFO_COUNT; i++) {
|
||||
for (i = 0; digest_info_prefix[i].algorithm != 0; i++) {
|
||||
size_t hdr_len = digest_info_prefix[i].hdr_len,
|
||||
hash_len = digest_info_prefix[i].hash_len;
|
||||
const u8 *hdr = digest_info_prefix[i].hdr;
|
||||
|
@ -239,21 +257,43 @@ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags,
|
|||
}
|
||||
}
|
||||
|
||||
/* strip leading zero padding (does only really work when a DigestInfo
|
||||
* value has been padded */
|
||||
int sc_strip_zero_padding(const u8 *in, size_t in_len, u8 *out,
|
||||
size_t *out_len)
|
||||
int sc_get_encoding_flags(sc_context_t *ctx,
|
||||
unsigned long iflags, unsigned long caps,
|
||||
unsigned long *pflags, unsigned long *sflags)
|
||||
{
|
||||
while (*in == 0 && in_len) {
|
||||
in++;
|
||||
in_len--;
|
||||
size_t i;
|
||||
|
||||
if (pflags == NULL || sflags == NULL)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
for (i = 0; digest_info_prefix[i].algorithm != 0; i++) {
|
||||
if (iflags & digest_info_prefix[i].algorithm) {
|
||||
if (digest_info_prefix[i].algorithm != SC_ALGORITHM_RSA_HASH_NONE &&
|
||||
caps & digest_info_prefix[i].algorithm)
|
||||
*sflags |= digest_info_prefix[i].algorithm;
|
||||
else
|
||||
*pflags |= digest_info_prefix[i].algorithm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (*out_len < in_len)
|
||||
return SC_ERROR_INTERNAL;
|
||||
|
||||
memmove(out, in, in_len);
|
||||
*out_len = in_len;
|
||||
if (iflags & SC_ALGORITHM_RSA_PAD_PKCS1) {
|
||||
if (caps & SC_ALGORITHM_RSA_PAD_PKCS1)
|
||||
*sflags |= SC_ALGORITHM_RSA_PAD_PKCS1;
|
||||
else
|
||||
*pflags |= SC_ALGORITHM_RSA_PAD_PKCS1;
|
||||
} else if ((iflags & SC_ALGORITHM_RSA_PADS) == SC_ALGORITHM_RSA_PAD_NONE) {
|
||||
if (!(caps & SC_ALGORITHM_RSA_RAW)) {
|
||||
sc_error(ctx, "raw RSA is not supported");
|
||||
return SC_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
*sflags |= SC_ALGORITHM_RSA_RAW;
|
||||
/* in case of raw RSA there is nothing to pad */
|
||||
*pflags = 0;
|
||||
} else {
|
||||
sc_error(ctx, "unsupported algorithm");
|
||||
return SC_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return SC_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* pkcs15-sec.c: PKCS#15 cryptography functions
|
||||
*
|
||||
* Copyright (C) 2001, 2002 Juha Yrjölä <juha.yrjola@iki.fi>
|
||||
* Copyrigth (C) 2007 Nils Larsch <nils@larsch.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -20,7 +21,6 @@
|
|||
|
||||
#include "internal.h"
|
||||
#include "pkcs15.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
@ -68,7 +68,7 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
|
|||
sc_security_env_t senv;
|
||||
sc_context_t *ctx = p15card->card->ctx;
|
||||
const struct sc_pkcs15_prkey_info *prkey = (const struct sc_pkcs15_prkey_info *) obj->data;
|
||||
unsigned long pad_flags = 0;
|
||||
unsigned long pad_flags = 0, sec_flags = 0;
|
||||
|
||||
SC_FUNC_CALLED(ctx, 1);
|
||||
/* If the key is extractable, the caller should extract the
|
||||
|
@ -87,27 +87,14 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
|
|||
return SC_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
senv.algorithm = SC_ALGORITHM_RSA;
|
||||
senv.algorithm_flags = 0;
|
||||
|
||||
if (flags & SC_ALGORITHM_RSA_PAD_PKCS1) {
|
||||
if (!(alg_info->flags & SC_ALGORITHM_RSA_PAD_PKCS1))
|
||||
pad_flags |= SC_ALGORITHM_RSA_PAD_PKCS1;
|
||||
else
|
||||
senv.algorithm_flags |= SC_ALGORITHM_RSA_PAD_PKCS1;
|
||||
} else if ((flags & SC_ALGORITHM_RSA_PAD_ANSI) ||
|
||||
(flags & SC_ALGORITHM_RSA_PAD_ISO9796)) {
|
||||
sc_error(ctx, "Only PKCS #1 padding method supported\n");
|
||||
return SC_ERROR_NOT_SUPPORTED;
|
||||
} else {
|
||||
if (!(alg_info->flags & SC_ALGORITHM_RSA_RAW)) {
|
||||
sc_error(ctx, "Card requires RSA padding\n");
|
||||
return SC_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
senv.algorithm_flags |= SC_ALGORITHM_RSA_RAW;
|
||||
}
|
||||
r = sc_get_encoding_flags(ctx, flags, alg_info->flags, &pad_flags, &sec_flags);
|
||||
if (r != SC_SUCCESS)
|
||||
return r;
|
||||
|
||||
senv.operation = SC_SEC_OPERATION_DECIPHER;
|
||||
senv.flags = 0;
|
||||
senv.algorithm_flags = sec_flags;
|
||||
senv.operation = SC_SEC_OPERATION_DECIPHER;
|
||||
senv.flags = 0;
|
||||
/* optional keyReference attribute (the default value is -1) */
|
||||
if (prkey->key_reference >= 0) {
|
||||
senv.key_ref_len = 1;
|
||||
|
@ -140,7 +127,7 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
|
|||
/* Strip any padding */
|
||||
if (pad_flags & SC_ALGORITHM_RSA_PAD_PKCS1) {
|
||||
r = sc_pkcs1_strip_02_padding(out, (size_t)r, out, (size_t *) &r);
|
||||
SC_TEST_RET(ctx, r, "Invalid PKCS#1 padding");
|
||||
SC_TEST_RET(ctx, r, "Invalid PKCS#1 padding");
|
||||
}
|
||||
|
||||
return r;
|
||||
|
@ -156,9 +143,9 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
|
|||
sc_context_t *ctx = p15card->card->ctx;
|
||||
sc_algorithm_info_t *alg_info;
|
||||
const struct sc_pkcs15_prkey_info *prkey = (const struct sc_pkcs15_prkey_info *) obj->data;
|
||||
u8 buf[512], *tmpin, *tmpout, *help;
|
||||
size_t tmpoutlen;
|
||||
unsigned long pad_flags = 0;
|
||||
u8 buf[512], *tmp;
|
||||
size_t modlen = prkey->modulus_length / 8;
|
||||
unsigned long pad_flags = 0, sec_flags = 0;
|
||||
|
||||
SC_FUNC_CALLED(ctx, 1);
|
||||
/* If the key is extractable, the caller should extract the
|
||||
|
@ -180,13 +167,10 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
|
|||
senv.algorithm = SC_ALGORITHM_RSA;
|
||||
|
||||
/* Probably never happens, but better make sure */
|
||||
if (inlen > sizeof(buf))
|
||||
if (inlen > sizeof(buf) || outlen < modlen)
|
||||
return SC_ERROR_BUFFER_TOO_SMALL;
|
||||
memcpy(buf, in, inlen);
|
||||
tmpin = buf;
|
||||
if (outlen < (prkey->modulus_length + 7) / 8)
|
||||
return SC_ERROR_BUFFER_TOO_SMALL;
|
||||
tmpout = out;
|
||||
tmp = buf;
|
||||
|
||||
/* flags: the requested algo
|
||||
* algo_info->flags: what is supported by the card
|
||||
|
@ -197,92 +181,38 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
|
|||
if ((flags == (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE)) &&
|
||||
!(alg_info->flags & (SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_NONE))) {
|
||||
unsigned int algo;
|
||||
tmpoutlen = sizeof(buf);
|
||||
r = sc_pkcs1_strip_digest_info_prefix(&algo, tmpin, inlen, tmpout, &tmpoutlen);
|
||||
if (r != SC_SUCCESS || algo == SC_ALGORITHM_RSA_HASH_NONE)
|
||||
size_t tmplen = sizeof(buf);
|
||||
r = sc_pkcs1_strip_digest_info_prefix(&algo, tmp, inlen, tmp, &tmplen);
|
||||
if (r != SC_SUCCESS || algo == SC_ALGORITHM_RSA_HASH_NONE) {
|
||||
sc_mem_clear(buf, sizeof(buf));
|
||||
return SC_ERROR_INVALID_DATA;
|
||||
help = tmpin;
|
||||
tmpin = tmpout;
|
||||
tmpout = help;
|
||||
inlen = tmpoutlen;
|
||||
}
|
||||
flags &= ~SC_ALGORITHM_RSA_HASH_NONE;
|
||||
flags |= algo;
|
||||
inlen = tmplen;
|
||||
}
|
||||
|
||||
senv.algorithm_flags = 0;
|
||||
if (flags & SC_ALGORITHM_RSA_HASH_SHA1) {
|
||||
if (inlen != 20)
|
||||
SC_FUNC_RETURN(ctx, 0, SC_ERROR_WRONG_LENGTH);
|
||||
if (!(alg_info->flags & SC_ALGORITHM_RSA_HASH_SHA1))
|
||||
pad_flags |= SC_ALGORITHM_RSA_HASH_SHA1;
|
||||
else
|
||||
senv.algorithm_flags |= SC_ALGORITHM_RSA_HASH_SHA1;
|
||||
} else if (flags & SC_ALGORITHM_RSA_HASH_MD5) {
|
||||
if (inlen != 16)
|
||||
SC_FUNC_RETURN(ctx, 0, SC_ERROR_WRONG_LENGTH);
|
||||
if (!(alg_info->flags & SC_ALGORITHM_RSA_HASH_MD5))
|
||||
pad_flags |= SC_ALGORITHM_RSA_HASH_MD5;
|
||||
else
|
||||
senv.algorithm_flags |= SC_ALGORITHM_RSA_HASH_MD5;
|
||||
} else if (flags & SC_ALGORITHM_RSA_HASH_RIPEMD160) {
|
||||
if (inlen != 20)
|
||||
SC_FUNC_RETURN(ctx, 0, SC_ERROR_WRONG_LENGTH);
|
||||
if (!(alg_info->flags & SC_ALGORITHM_RSA_HASH_RIPEMD160))
|
||||
pad_flags |= SC_ALGORITHM_RSA_HASH_RIPEMD160;
|
||||
else
|
||||
senv.algorithm_flags |= SC_ALGORITHM_RSA_HASH_RIPEMD160;
|
||||
} else if (flags & SC_ALGORITHM_RSA_HASH_MD5_SHA1) {
|
||||
if (inlen != 36)
|
||||
SC_FUNC_RETURN(ctx, 0, SC_ERROR_WRONG_LENGTH);
|
||||
if (!(alg_info->flags & SC_ALGORITHM_RSA_HASH_MD5_SHA1))
|
||||
pad_flags |= SC_ALGORITHM_RSA_HASH_MD5_SHA1;
|
||||
else
|
||||
senv.algorithm_flags |= SC_ALGORITHM_RSA_HASH_MD5_SHA1;
|
||||
} else if (flags & SC_ALGORITHM_RSA_HASH_NONE ||
|
||||
(flags & SC_ALGORITHM_RSA_HASHES) == 0) {
|
||||
pad_flags |= SC_ALGORITHM_RSA_HASH_NONE;
|
||||
r = sc_get_encoding_flags(ctx, flags, alg_info->flags, &pad_flags, &sec_flags);
|
||||
if (r != SC_SUCCESS) {
|
||||
sc_mem_clear(buf, sizeof(buf));
|
||||
return r;
|
||||
}
|
||||
senv.algorithm_flags = sec_flags;
|
||||
|
||||
if (flags & SC_ALGORITHM_RSA_PAD_PKCS1) {
|
||||
if (!(alg_info->flags & SC_ALGORITHM_RSA_PAD_PKCS1))
|
||||
pad_flags |= SC_ALGORITHM_RSA_PAD_PKCS1;
|
||||
else
|
||||
senv.algorithm_flags |= SC_ALGORITHM_RSA_PAD_PKCS1;
|
||||
} else if ((flags & SC_ALGORITHM_RSA_PAD_ANSI) ||
|
||||
(flags & SC_ALGORITHM_RSA_PAD_ISO9796)) {
|
||||
sc_error(ctx, "Only PKCS #1 padding method supported\n");
|
||||
return SC_ERROR_NOT_SUPPORTED;
|
||||
} else {
|
||||
if (!(alg_info->flags & SC_ALGORITHM_RSA_RAW)) {
|
||||
sc_error(ctx, "Card requires RSA padding\n");
|
||||
return SC_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
senv.algorithm_flags |= SC_ALGORITHM_RSA_RAW;
|
||||
pad_flags = 0;
|
||||
|
||||
/* Add zero-padding if input shorter than modulus */
|
||||
if (inlen < prkey->modulus_length/8) {
|
||||
unsigned int modulus_len = prkey->modulus_length/8;
|
||||
if (modulus_len > sizeof(buf))
|
||||
return SC_ERROR_BUFFER_TOO_SMALL;
|
||||
memset(tmpout, 0, sizeof(buf));
|
||||
memcpy(tmpout + modulus_len - inlen, tmpin, inlen);
|
||||
inlen = modulus_len;
|
||||
help = tmpin;
|
||||
tmpin = tmpout;
|
||||
tmpout = help;
|
||||
}
|
||||
}
|
||||
|
||||
if (pad_flags) {
|
||||
tmpoutlen = sizeof(buf);
|
||||
r = sc_pkcs1_encode(ctx, pad_flags, tmpin, inlen, tmpout, &tmpoutlen,
|
||||
prkey->modulus_length/8);
|
||||
/* add the padding bytes (if necessary) */
|
||||
if (pad_flags != 0) {
|
||||
size_t tmplen = sizeof(buf);
|
||||
r = sc_pkcs1_encode(ctx, pad_flags, tmp, inlen, tmp, &tmplen, modlen);
|
||||
SC_TEST_RET(ctx, r, "Unable to add padding");
|
||||
help = tmpin;
|
||||
tmpin = tmpout;
|
||||
tmpout = help;
|
||||
inlen = tmpoutlen;
|
||||
inlen = tmplen;
|
||||
} else if ((flags & SC_ALGORITHM_RSA_PADS) == SC_ALGORITHM_RSA_PAD_NONE) {
|
||||
/* Add zero-padding if input is shorter than the modulus */
|
||||
if (inlen < modlen) {
|
||||
if (modlen > sizeof(buf))
|
||||
return SC_ERROR_BUFFER_TOO_SMALL;
|
||||
memmove(tmp+modlen-inlen, tmp, inlen);
|
||||
memset(tmp, 0, modlen-inlen);
|
||||
}
|
||||
}
|
||||
|
||||
senv.operation = SC_SEC_OPERATION_SIGN;
|
||||
|
@ -298,8 +228,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
|
|||
r = sc_lock(p15card->card);
|
||||
SC_TEST_RET(ctx, r, "sc_lock() failed");
|
||||
|
||||
if (prkey->path.len != 0)
|
||||
{
|
||||
if (prkey->path.len != 0) {
|
||||
r = select_key_file(p15card, prkey, &senv);
|
||||
if (r < 0) {
|
||||
sc_unlock(p15card->card);
|
||||
|
@ -313,20 +242,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
|
|||
SC_TEST_RET(ctx, r, "sc_set_security_env() failed");
|
||||
}
|
||||
|
||||
/* XXX: Should we adjust outlen to match the size of
|
||||
* the signature we expect? CardOS for instance will
|
||||
* barf if the LE value doesn't match the size of the
|
||||
* signature exactly.
|
||||
*
|
||||
* Right now we work around this by assuming that eToken keys
|
||||
* always have algorithm RSA_PURE_SIG so the input buffer
|
||||
* is padded and has the same length as the signature. --okir
|
||||
*/
|
||||
if (tmpin == out) {
|
||||
memcpy(tmpout, tmpin, inlen);
|
||||
tmpin = tmpout;
|
||||
}
|
||||
r = sc_compute_signature(p15card->card, tmpin, inlen, out, outlen);
|
||||
r = sc_compute_signature(p15card->card, tmp, inlen, out, outlen);
|
||||
sc_mem_clear(buf, sizeof(buf));
|
||||
sc_unlock(p15card->card);
|
||||
SC_TEST_RET(ctx, r, "sc_compute_signature() failed");
|
||||
|
|
|
@ -1947,6 +1947,15 @@ static CK_RV pkcs15_prkey_sign(struct sc_pkcs11_session *ses, void *obj,
|
|||
case CKM_SHA1_RSA_PKCS:
|
||||
flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA1;
|
||||
break;
|
||||
case CKM_SHA256_RSA_PKCS:
|
||||
flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA256;
|
||||
break;
|
||||
case CKM_SHA384_RSA_PKCS:
|
||||
flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA384;
|
||||
break;
|
||||
case CKM_SHA512_RSA_PKCS:
|
||||
flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA512;
|
||||
break;
|
||||
case CKM_RIPEMD160_RSA_PKCS:
|
||||
flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_RIPEMD160;
|
||||
break;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
static CK_RV sc_pkcs11_openssl_md_init(sc_pkcs11_operation_t *);
|
||||
static CK_RV sc_pkcs11_openssl_md_update(sc_pkcs11_operation_t *,
|
||||
|
@ -30,6 +31,38 @@ static sc_pkcs11_mechanism_type_t openssl_sha1_mech = {
|
|||
sc_pkcs11_openssl_md_final
|
||||
};
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00908000L
|
||||
static sc_pkcs11_mechanism_type_t openssl_sha256_mech = {
|
||||
CKM_SHA256,
|
||||
{ 0, 0, CKF_DIGEST }, 0,
|
||||
sizeof(struct sc_pkcs11_operation),
|
||||
sc_pkcs11_openssl_md_release,
|
||||
sc_pkcs11_openssl_md_init,
|
||||
sc_pkcs11_openssl_md_update,
|
||||
sc_pkcs11_openssl_md_final
|
||||
};
|
||||
|
||||
static sc_pkcs11_mechanism_type_t openssl_sha384_mech = {
|
||||
CKM_SHA384,
|
||||
{ 0, 0, CKF_DIGEST }, 0,
|
||||
sizeof(struct sc_pkcs11_operation),
|
||||
sc_pkcs11_openssl_md_release,
|
||||
sc_pkcs11_openssl_md_init,
|
||||
sc_pkcs11_openssl_md_update,
|
||||
sc_pkcs11_openssl_md_final
|
||||
};
|
||||
|
||||
static sc_pkcs11_mechanism_type_t openssl_sha512_mech = {
|
||||
CKM_SHA512,
|
||||
{ 0, 0, CKF_DIGEST }, 0,
|
||||
sizeof(struct sc_pkcs11_operation),
|
||||
sc_pkcs11_openssl_md_release,
|
||||
sc_pkcs11_openssl_md_init,
|
||||
sc_pkcs11_openssl_md_update,
|
||||
sc_pkcs11_openssl_md_final
|
||||
};
|
||||
#endif
|
||||
|
||||
static sc_pkcs11_mechanism_type_t openssl_md5_mech = {
|
||||
CKM_MD5,
|
||||
{ 0, 0, CKF_DIGEST }, 0,
|
||||
|
@ -55,6 +88,14 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *card)
|
|||
{
|
||||
openssl_sha1_mech.mech_data = EVP_sha1();
|
||||
sc_pkcs11_register_mechanism(card, &openssl_sha1_mech);
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00908000L
|
||||
openssl_sha256_mech.mech_data = EVP_sha256();
|
||||
sc_pkcs11_register_mechanism(card, &openssl_sha256_mech);
|
||||
openssl_sha384_mech.mech_data = EVP_sha384();
|
||||
sc_pkcs11_register_mechanism(card, &openssl_sha384_mech);
|
||||
openssl_sha512_mech.mech_data = EVP_sha512();
|
||||
sc_pkcs11_register_mechanism(card, &openssl_sha512_mech);
|
||||
#endif
|
||||
openssl_md5_mech.mech_data = EVP_md5();
|
||||
sc_pkcs11_register_mechanism(card, &openssl_md5_mech);
|
||||
openssl_ripemd160_mech.mech_data = EVP_ripemd160();
|
||||
|
|
|
@ -230,6 +230,9 @@ enum_specs ck_mec_s[] = {
|
|||
{ CKM_MD2_RSA_PKCS , "CKM_MD2_RSA_PKCS " },
|
||||
{ CKM_MD5_RSA_PKCS , "CKM_MD5_RSA_PKCS " },
|
||||
{ CKM_SHA1_RSA_PKCS , "CKM_SHA1_RSA_PKCS " },
|
||||
{ CKM_SHA256_RSA_PKCS , "CKM_SHA256_RSA_PKCS " },
|
||||
{ CKM_SHA384_RSA_PKCS , "CKM_SHA384_RSA_PKCS " },
|
||||
{ CKM_SHA512_RSA_PKCS , "CKM_SHA512_RSA_PKCS " },
|
||||
{ CKM_RIPEMD128_RSA_PKCS , "CKM_RIPEMD128_RSA_PKCS " },
|
||||
{ CKM_RIPEMD160_RSA_PKCS , "CKM_RIPEMD160_RSA_PKCS " },
|
||||
{ CKM_RSA_PKCS_OAEP , "CKM_RSA_PKCS_OAEP " },
|
||||
|
@ -238,6 +241,9 @@ enum_specs ck_mec_s[] = {
|
|||
{ CKM_SHA1_RSA_X9_31 , "CKM_SHA1_RSA_X9_31 " },
|
||||
{ CKM_RSA_PKCS_PSS , "CKM_RSA_PKCS_PSS " },
|
||||
{ CKM_SHA1_RSA_PKCS_PSS , "CKM_SHA1_RSA_PKCS_PSS " },
|
||||
{ CKM_SHA256_RSA_PKCS_PSS , "CKM_SHA256_RSA_PKCS_PSS " },
|
||||
{ CKM_SHA384_RSA_PKCS_PSS , "CKM_SHA384_RSA_PKCS_PSS " },
|
||||
{ CKM_SHA512_RSA_PKCS_PSS , "CKM_SHA512_RSA_PKCS_PSS " },
|
||||
{ CKM_DSA_KEY_PAIR_GEN , "CKM_DSA_KEY_PAIR_GEN " },
|
||||
{ CKM_DSA , "CKM_DSA " },
|
||||
{ CKM_DSA_SHA1 , "CKM_DSA_SHA1 " },
|
||||
|
|
|
@ -498,6 +498,12 @@ typedef unsigned long ck_mechanism_type_t;
|
|||
#define CKM_X9_42_DH_DERIVE (0x31)
|
||||
#define CKM_X9_42_DH_HYBRID_DERIVE (0x32)
|
||||
#define CKM_X9_42_MQV_DERIVE (0x33)
|
||||
#define CKM_SHA256_RSA_PKCS (0x40)
|
||||
#define CKM_SHA384_RSA_PKCS (0x41)
|
||||
#define CKM_SHA512_RSA_PKCS (0x42)
|
||||
#define CKM_SHA256_RSA_PKCS_PSS (0x43)
|
||||
#define CKM_SHA384_RSA_PKCS_PSS (0x44)
|
||||
#define CKM_SHA512_RSA_PKCS_PSS (0x45)
|
||||
#define CKM_RC2_KEY_GEN (0x100)
|
||||
#define CKM_RC2_ECB (0x101)
|
||||
#define CKM_RC2_CBC (0x102)
|
||||
|
@ -540,6 +546,15 @@ typedef unsigned long ck_mechanism_type_t;
|
|||
#define CKM_RIPEMD160 (0x240)
|
||||
#define CKM_RIPEMD160_HMAC (0x241)
|
||||
#define CKM_RIPEMD160_HMAC_GENERAL (0x242)
|
||||
#define CKM_SHA256 (0x250)
|
||||
#define CKM_SHA256_HMAC (0x251)
|
||||
#define CKM_SHA256_HMAC_GENERAL (0x252)
|
||||
#define CKM_SHA384 (0x260)
|
||||
#define CKM_SHA384_HMAC (0x261)
|
||||
#define CKM_SHA384_HMAC_GENERAL (0x262)
|
||||
#define CKM_SHA512 (0x270)
|
||||
#define CKM_SHA512_HMAC (0x271)
|
||||
#define CKM_SHA512_HMAC_GENERAL (0x272)
|
||||
#define CKM_CAST_KEY_GEN (0x300)
|
||||
#define CKM_CAST_ECB (0x301)
|
||||
#define CKM_CAST_CBC (0x302)
|
||||
|
|
|
@ -3329,6 +3329,9 @@ static struct mech_info p11_mechanisms[] = {
|
|||
{ CKM_MD2_RSA_PKCS, "MD2-RSA-PKCS", NULL },
|
||||
{ CKM_MD5_RSA_PKCS, "MD5-RSA-PKCS", "rsa-md5" },
|
||||
{ CKM_SHA1_RSA_PKCS, "SHA1-RSA-PKCS", "rsa-sha1" },
|
||||
{ CKM_SHA256_RSA_PKCS, "SHA256-RSA-PKCS", "rsa-sha256" },
|
||||
{ CKM_SHA384_RSA_PKCS, "SHA384-RSA-PKCS", "rsa-sha384" },
|
||||
{ CKM_SHA512_RSA_PKCS, "SHA512-RSA-PKCS", "rsa-sha512" },
|
||||
{ CKM_RIPEMD128_RSA_PKCS, "RIPEMD128-RSA-PKCS", NULL },
|
||||
{ CKM_RIPEMD160_RSA_PKCS, "RIPEMD160-RSA-PKCS", "rsa-ripemd160" },
|
||||
{ CKM_RSA_PKCS_OAEP, "RSA-PKCS-OAEP", NULL },
|
||||
|
@ -3337,6 +3340,9 @@ static struct mech_info p11_mechanisms[] = {
|
|||
{ CKM_SHA1_RSA_X9_31, "SHA1-RSA-X9-31", NULL },
|
||||
{ CKM_RSA_PKCS_PSS, "RSA-PKCS-PSS", NULL },
|
||||
{ CKM_SHA1_RSA_PKCS_PSS, "SHA1-RSA-PKCS-PSS", NULL },
|
||||
{ CKM_SHA256_RSA_PKCS, "SHA256-RSA-PKCS-PSS", NULL },
|
||||
{ CKM_SHA384_RSA_PKCS, "SHA384-RSA-PKCS-PSS", NULL },
|
||||
{ CKM_SHA512_RSA_PKCS, "SHA512-RSA-PKCS-PSS", NULL },
|
||||
{ CKM_DSA_KEY_PAIR_GEN, "DSA-KEY-PAIR-GEN", NULL },
|
||||
{ CKM_DSA, "DSA", NULL },
|
||||
{ CKM_DSA_SHA1, "DSA-SHA1", NULL },
|
||||
|
@ -3382,6 +3388,9 @@ static struct mech_info p11_mechanisms[] = {
|
|||
{ CKM_SHA_1, "SHA-1", NULL },
|
||||
{ CKM_SHA_1_HMAC, "SHA-1-HMAC", NULL },
|
||||
{ CKM_SHA_1_HMAC_GENERAL, "SHA-1-HMAC-GENERAL", NULL },
|
||||
{ CKM_SHA256, "SHA256", NULL },
|
||||
{ CKM_SHA384, "SHA384", NULL },
|
||||
{ CKM_SHA512, "SHA512", NULL },
|
||||
{ CKM_RIPEMD128, "RIPEMD128", NULL },
|
||||
{ CKM_RIPEMD128_HMAC, "RIPEMD128-HMAC", NULL },
|
||||
{ CKM_RIPEMD128_HMAC_GENERAL,"RIPEMD128-HMAC-GENERAL", NULL },
|
||||
|
|
|
@ -46,6 +46,10 @@ int opt_crypt_flags = 0;
|
|||
|
||||
enum {
|
||||
OPT_SHA1 = 0x100,
|
||||
OPT_SHA256,
|
||||
OPT_SHA384,
|
||||
OPT_SHA512,
|
||||
OPT_SHA224,
|
||||
OPT_MD5,
|
||||
OPT_PKCS1,
|
||||
};
|
||||
|
@ -59,6 +63,10 @@ const struct option options[] = {
|
|||
{ "output", 1, 0, 'o' },
|
||||
{ "raw", 0, 0, 'R' },
|
||||
{ "sha-1", 0, 0, OPT_SHA1 },
|
||||
{ "sha-256", 0, 0, OPT_SHA256 },
|
||||
{ "sha-384", 0, 0, OPT_SHA384 },
|
||||
{ "sha-512", 0, 0, OPT_SHA512 },
|
||||
{ "sha-224", 0, 0, OPT_SHA224 },
|
||||
{ "md5", 0, 0, OPT_MD5 },
|
||||
{ "pkcs1", 0, 0, OPT_PKCS1 },
|
||||
{ "pin", 1, 0, 'p' },
|
||||
|
@ -76,6 +84,10 @@ const char *option_help[] = {
|
|||
"Outputs to file <arg>",
|
||||
"Outputs raw 8 bit data",
|
||||
"Input file is a SHA-1 hash",
|
||||
"Input file is a SHA-256 hash",
|
||||
"Input file is a SHA-384 hash",
|
||||
"Input file is a SHA-512 hash",
|
||||
"Input file is a SHA-224 hash",
|
||||
"Input file is a MD5 hash",
|
||||
"Use PKCS #1 v1.5 padding",
|
||||
"Uses password (PIN) <arg> (use - for reading PIN from STDIN)",
|
||||
|
@ -510,6 +522,18 @@ int main(int argc, char * const argv[])
|
|||
case OPT_SHA1:
|
||||
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA1;
|
||||
break;
|
||||
case OPT_SHA256:
|
||||
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA256;
|
||||
break;
|
||||
case OPT_SHA384:
|
||||
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA384;
|
||||
break;
|
||||
case OPT_SHA512:
|
||||
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA512;
|
||||
break;
|
||||
case OPT_SHA224:
|
||||
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA224;
|
||||
break;
|
||||
case OPT_MD5:
|
||||
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5;
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue