Skip to content

Commit a2f622a

Browse files
author
nils
committed
implement support for SHA2 (still experimental)
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3115 c6295689-39f2-0310-b995-f0e70906c6a9
1 parent 1b4472c commit a2f622a

File tree

12 files changed

+258
-165
lines changed

12 files changed

+258
-165
lines changed

src/libopensc/card-cardos.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -783,11 +783,16 @@ cardos_compute_signature(sc_card_t *card, const u8 *data, size_t datalen,
783783
/* remove padding: first try pkcs1 bt01 padding */
784784
r = sc_pkcs1_strip_01_padding(data, datalen, buf, &tmp_len);
785785
if (r != SC_SUCCESS) {
786-
/* no pkcs1 bt01 padding => let's try zero padding */
786+
const u8 *p = data;
787+
/* no pkcs1 bt01 padding => let's try zero padding
788+
* This can only work if the data tbs doesn't have a
789+
* leading 0 byte. */
787790
tmp_len = buf_len;
788-
r = sc_strip_zero_padding(data, datalen, buf, &tmp_len);
789-
if (r != SC_SUCCESS)
790-
SC_FUNC_RETURN(ctx, 4, r);
791+
while (*p == 0 && tmp_len != 0) {
792+
++p;
793+
--tmp_len;
794+
}
795+
memcpy(buf, p, tmp_len);
791796
}
792797
sc_ctx_suppress_errors_on(ctx);
793798
r = do_compute_signature(card, buf, tmp_len, out, outlen);

src/libopensc/card-incrypto34.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -568,11 +568,16 @@ incrypto34_compute_signature(sc_card_t *card, const u8 *data, size_t datalen,
568568
/* remove padding: first try pkcs1 bt01 padding */
569569
r = sc_pkcs1_strip_01_padding(data, datalen, buf, &tmp_len);
570570
if (r != SC_SUCCESS) {
571-
/* no pkcs1 bt01 padding => let's try zero padding */
571+
const u8 *p = data;
572+
/* no pkcs1 bt01 padding => let's try zero padding.
573+
* This can only work if the data tbs doesn't have a
574+
* leading 0 byte. */
572575
tmp_len = buf_len;
573-
r = sc_strip_zero_padding(data, datalen, buf, &tmp_len);
574-
if (r != SC_SUCCESS)
575-
SC_FUNC_RETURN(ctx, 4, r);
576+
while (*p == 0 && tmp_len != 0) {
577+
++p;
578+
--tmp_len;
579+
}
580+
memcpy(buf, p, tmp_len);
576581
}
577582
sc_ctx_suppress_errors_on(ctx);
578583
r = do_compute_signature(card, buf, tmp_len, out, outlen);

src/libopensc/internal.h

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,19 +123,38 @@ int sc_asn1_read_tag(const u8 ** buf, size_t buflen, unsigned int *cla_out,
123123
/* pkcs1 padding/encoding functions */
124124
/********************************************************************/
125125

126-
int sc_pkcs1_add_01_padding(const u8 *in, size_t in_len, u8 *out,
127-
size_t *out_len, size_t mod_length);
128126
int sc_pkcs1_strip_01_padding(const u8 *in_dat, size_t in_len, u8 *out_dat,
129127
size_t *out_len);
130128
int sc_pkcs1_strip_02_padding(const u8 *data, size_t len, u8 *out_dat,
131129
size_t *out_len);
132-
int sc_pkcs1_add_digest_info_prefix(unsigned int algorithm, const u8 *in_dat,
133-
size_t in_len, u8 *out_dat, size_t *out_len);
134130
int sc_pkcs1_strip_digest_info_prefix(unsigned int *algorithm,
135131
const u8 *in_dat, size_t in_len, u8 *out_dat, size_t *out_len);
132+
133+
/**
134+
* PKCS1 encodes the given data.
135+
* @param ctx IN sc_context_t object
136+
* @param flags IN the algorithm to use
137+
* @param in IN input buffer
138+
* @param inlen IN length of the input
139+
* @param out OUT output buffer (in == out is allowed)
140+
* @param outlen OUT length of the output buffer
141+
* @param modlen IN length of the modulus in bytes
142+
* @return SC_SUCCESS on success and an error code otherwise
143+
*/
136144
int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags,
137-
const u8 *in, size_t in_len, u8 *out, size_t *out_len, size_t mod_len);
138-
int sc_strip_zero_padding(const u8 *in,size_t in_len, u8 *out, size_t *out_len);
145+
const u8 *in, size_t inlen, u8 *out, size_t *outlen, size_t modlen);
146+
/**
147+
* Get the necessary padding and sec. env. flags.
148+
* @param ctx IN sc_contex_t object
149+
* @param iflags IN the desired algorithms flags
150+
* @param caps IN the card / key capabilities
151+
* @param pflags OUT the padding flags to use
152+
* @param salg OUT the security env. algorithm flag to use
153+
* @return SC_SUCCESS on success and an error code otherwise
154+
*/
155+
int sc_get_encoding_flags(sc_context_t *ctx,
156+
unsigned long iflags, unsigned long caps,
157+
unsigned long *pflags, unsigned long *salg);
139158

140159
/********************************************************************/
141160
/* mutex functions */

src/libopensc/opensc.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,15 @@ extern "C" {
181181
/* If the card is willing to produce a cryptogram with the following
182182
* hash values, set these flags accordingly. */
183183
#define SC_ALGORITHM_RSA_HASH_NONE 0x00000010
184-
#define SC_ALGORITHM_RSA_HASHES 0x000001E0
185184
#define SC_ALGORITHM_RSA_HASH_SHA1 0x00000020
186185
#define SC_ALGORITHM_RSA_HASH_MD5 0x00000040
187186
#define SC_ALGORITHM_RSA_HASH_MD5_SHA1 0x00000080
188187
#define SC_ALGORITHM_RSA_HASH_RIPEMD160 0x00000100
188+
#define SC_ALGORITHM_RSA_HASH_SHA256 0x00000200
189+
#define SC_ALGORITHM_RSA_HASH_SHA384 0x00000400
190+
#define SC_ALGORITHM_RSA_HASH_SHA512 0x00000800
191+
#define SC_ALGORITHM_RSA_HASH_SHA224 0x00001000
192+
#define SC_ALGORITHM_RSA_HASHES 0x00001FE0
189193

190194
/* Event masks for sc_wait_for_event() */
191195
#define SC_EVENT_CARD_INSERTED 0x0001

src/libopensc/padding.c

Lines changed: 67 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/*
2-
* sc-padding.c: miscellaneous padding functions
2+
* padding.c: miscellaneous padding functions
33
*
44
* Copyright (C) 2001, 2002 Juha Yrjölä <[email protected]>
5-
* Copyright (C) 2003 Nils Larsch <[email protected]>
5+
* Copyright (C) 2003 - 2007 Nils Larsch <[email protected]>
66
*
77
* This library is free software; you can redistribute it and/or
88
* modify it under the terms of the GNU Lesser General Public
@@ -22,7 +22,6 @@
2222
#include "internal.h"
2323
#include <string.h>
2424
#include <stdlib.h>
25-
#include <assert.h>
2625

2726
/* TODO doxygen comments */
2827

@@ -37,31 +36,50 @@ static const u8 hdr_sha1[] = {
3736
0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a,
3837
0x05, 0x00, 0x04, 0x14
3938
};
39+
static const u8 hdr_sha256[] = {
40+
0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
41+
0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
42+
};
43+
static const u8 hdr_sha384[] = {
44+
0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
45+
0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30
46+
};
47+
static const u8 hdr_sha512[] = {
48+
0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
49+
0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40
50+
};
51+
static const u8 hdr_sha224[] = {
52+
0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
53+
0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c
54+
};
4055
static const u8 hdr_ripemd160[] = {
4156
0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, 0x02, 0x01,
4257
0x05, 0x00, 0x04, 0x14
4358
};
4459

4560

46-
#define DIGEST_INFO_COUNT 6
4761
static const struct digest_info_prefix {
4862
unsigned int algorithm;
4963
const u8 * hdr;
5064
size_t hdr_len;
5165
size_t hash_len;
52-
} digest_info_prefix[DIGEST_INFO_COUNT] = {
66+
} digest_info_prefix[] = {
5367
{ SC_ALGORITHM_RSA_HASH_NONE, NULL, 0, 0 },
5468
{ SC_ALGORITHM_RSA_HASH_MD5, hdr_md5, sizeof(hdr_md5), 16 },
5569
{ SC_ALGORITHM_RSA_HASH_SHA1, hdr_sha1, sizeof(hdr_sha1), 20 },
70+
{ SC_ALGORITHM_RSA_HASH_SHA256, hdr_sha256, sizeof(hdr_sha256), 32 },
71+
{ SC_ALGORITHM_RSA_HASH_SHA384, hdr_sha384, sizeof(hdr_sha384), 48 },
72+
{ SC_ALGORITHM_RSA_HASH_SHA512, hdr_sha512, sizeof(hdr_sha512), 64 },
73+
{ SC_ALGORITHM_RSA_HASH_SHA224, hdr_sha224, sizeof(hdr_sha224), 28 },
5674
{ SC_ALGORITHM_RSA_HASH_RIPEMD160,hdr_ripemd160, sizeof(hdr_ripemd160), 20 },
5775
{ SC_ALGORITHM_RSA_HASH_MD5_SHA1, NULL, 0, 36 },
5876
{ 0, NULL, 0, 0 }
5977
};
6078

6179
/* add/remove pkcs1 BT01 padding */
6280

63-
int sc_pkcs1_add_01_padding(const u8 *in, size_t in_len, u8 *out,
64-
size_t *out_len, size_t mod_length)
81+
static int sc_pkcs1_add_01_padding(const u8 *in, size_t in_len,
82+
u8 *out, size_t *out_len, size_t mod_length)
6583
{
6684
size_t i;
6785

@@ -82,15 +100,15 @@ int sc_pkcs1_add_01_padding(const u8 *in, size_t in_len, u8 *out,
82100
return SC_SUCCESS;
83101
}
84102

85-
int sc_pkcs1_strip_01_padding(const u8 *in_dat, size_t in_len, u8 *out,
86-
size_t *out_len)
103+
int sc_pkcs1_strip_01_padding(const u8 *in_dat, size_t in_len,
104+
u8 *out, size_t *out_len)
87105
{
88106
const u8 *tmp = in_dat;
89107
size_t len;
90108

91109
if (in_dat == NULL || in_len < 10)
92110
return SC_ERROR_INTERNAL;
93-
/* ignore leading zero byte */
111+
/* skip leading zero byte */
94112
if (*tmp == 0) {
95113
tmp++;
96114
in_len--;
@@ -122,7 +140,7 @@ int sc_pkcs1_strip_02_padding(const u8 *data, size_t len, u8 *out,
122140

123141
if (data == NULL || len < 3)
124142
return SC_ERROR_INTERNAL;
125-
/* skip leading zero octet (not part of the pkcs1 BT02 padding) */
143+
/* skip leading zero byte */
126144
if (*data == 0) {
127145
data++;
128146
len--;
@@ -147,12 +165,12 @@ int sc_pkcs1_strip_02_padding(const u8 *data, size_t len, u8 *out,
147165
}
148166

149167
/* add/remove DigestInfo prefix */
150-
int sc_pkcs1_add_digest_info_prefix(unsigned int algorithm, const u8 *in,
151-
size_t in_len, u8 *out, size_t *out_len)
168+
static int sc_pkcs1_add_digest_info_prefix(unsigned int algorithm,
169+
const u8 *in, size_t in_len, u8 *out, size_t *out_len)
152170
{
153171
int i;
154172

155-
for (i = 0; i < DIGEST_INFO_COUNT; i++) {
173+
for (i = 0; digest_info_prefix[i].algorithm != 0; i++) {
156174
if (algorithm == digest_info_prefix[i].algorithm) {
157175
const u8 *hdr = digest_info_prefix[i].hdr;
158176
size_t hdr_len = digest_info_prefix[i].hdr_len,
@@ -175,7 +193,7 @@ int sc_pkcs1_strip_digest_info_prefix(unsigned int *algorithm,
175193
{
176194
int i;
177195

178-
for (i = 0; i < DIGEST_INFO_COUNT; i++) {
196+
for (i = 0; digest_info_prefix[i].algorithm != 0; i++) {
179197
size_t hdr_len = digest_info_prefix[i].hdr_len,
180198
hash_len = digest_info_prefix[i].hash_len;
181199
const u8 *hdr = digest_info_prefix[i].hdr;
@@ -239,21 +257,43 @@ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags,
239257
}
240258
}
241259

242-
/* strip leading zero padding (does only really work when a DigestInfo
243-
* value has been padded */
244-
int sc_strip_zero_padding(const u8 *in, size_t in_len, u8 *out,
245-
size_t *out_len)
260+
int sc_get_encoding_flags(sc_context_t *ctx,
261+
unsigned long iflags, unsigned long caps,
262+
unsigned long *pflags, unsigned long *sflags)
246263
{
247-
while (*in == 0 && in_len) {
248-
in++;
249-
in_len--;
250-
}
264+
size_t i;
251265

252-
if (*out_len < in_len)
253-
return SC_ERROR_INTERNAL;
266+
if (pflags == NULL || sflags == NULL)
267+
return SC_ERROR_INVALID_ARGUMENTS;
268+
269+
for (i = 0; digest_info_prefix[i].algorithm != 0; i++) {
270+
if (iflags & digest_info_prefix[i].algorithm) {
271+
if (digest_info_prefix[i].algorithm != SC_ALGORITHM_RSA_HASH_NONE &&
272+
caps & digest_info_prefix[i].algorithm)
273+
*sflags |= digest_info_prefix[i].algorithm;
274+
else
275+
*pflags |= digest_info_prefix[i].algorithm;
276+
break;
277+
}
278+
}
254279

255-
memmove(out, in, in_len);
256-
*out_len = in_len;
280+
if (iflags & SC_ALGORITHM_RSA_PAD_PKCS1) {
281+
if (caps & SC_ALGORITHM_RSA_PAD_PKCS1)
282+
*sflags |= SC_ALGORITHM_RSA_PAD_PKCS1;
283+
else
284+
*pflags |= SC_ALGORITHM_RSA_PAD_PKCS1;
285+
} else if ((iflags & SC_ALGORITHM_RSA_PADS) == SC_ALGORITHM_RSA_PAD_NONE) {
286+
if (!(caps & SC_ALGORITHM_RSA_RAW)) {
287+
sc_error(ctx, "raw RSA is not supported");
288+
return SC_ERROR_NOT_SUPPORTED;
289+
}
290+
*sflags |= SC_ALGORITHM_RSA_RAW;
291+
/* in case of raw RSA there is nothing to pad */
292+
*pflags = 0;
293+
} else {
294+
sc_error(ctx, "unsupported algorithm");
295+
return SC_ERROR_NOT_SUPPORTED;
296+
}
257297

258298
return SC_SUCCESS;
259299
}

0 commit comments

Comments
 (0)