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:
nils 2007-02-02 22:15:14 +00:00
parent 1b4472ca9f
commit a2f622a215
12 changed files with 259 additions and 166 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -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

View File

@ -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;
}

View File

@ -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");

View File

@ -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;

View File

@ -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();

View File

@ -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 " },

View File

@ -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)

View File

@ -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 },

View File

@ -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;