2003-07-15 10:49:28 +00:00
/*
2007-02-02 22:15:14 +00:00
* padding . c : miscellaneous padding functions
2003-07-15 10:49:28 +00:00
*
2006-12-19 21:31:17 +00:00
* Copyright ( C ) 2001 , 2002 Juha Yrjölä < juha . yrjola @ iki . fi >
2007-02-02 22:15:14 +00:00
* Copyright ( C ) 2003 - 2007 Nils Larsch < larsch @ trustcenter . de >
2003-07-15 10:49:28 +00:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
2015-04-22 21:55:33 +00:00
# if HAVE_CONFIG_H
2010-03-04 08:14:36 +00:00
# include "config.h"
2015-04-22 21:55:33 +00:00
# endif
2010-03-04 08:14:36 +00:00
Add support for PSS padding to RSA signatures
A card driver may declare support for computing the padding on the card,
or else the padding will be applied locally in padding.c. All five
PKCS11 PSS mechanisms are supported, for signature and verification.
There are a few limits on what we choose to support, in particular I
don't see a need for arbitrary combinations of MGF hash, data hash, and
salt length, so I've restricted it (for the user's benefit) to the only
cases that really matter, where salt_len = hash_len and the same hash is
used for the MGF and data hashing.
------------------------------------------------------------------------
Reworked and extended in 2018 by Jakub Jelen <jjelen@redhat.com> against
current OpenSC master, to actually work with existing PIV cards:
* extended of missing mechanisms (SHA224, possibility to select MGF1)
* compatibility with OpenSSL 1.1+
* Removed the ANSI padding
* Formatting cleanup, error checking
Based on the original work from
https://github.com/NWilson/OpenSC/commit/42f3199e66
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2015-08-25 11:45:27 +00:00
# ifdef ENABLE_OPENSSL
# include <openssl/evp.h>
# include <openssl/rand.h>
# include <openssl/sha.h>
# endif
2003-07-15 10:49:28 +00:00
# include <string.h>
# include <stdlib.h>
2010-03-04 08:14:36 +00:00
# include "internal.h"
2003-07-15 10:49:28 +00:00
/* TODO doxygen comments */
/*
* Prefixes for pkcs - v1 signatures
*/
static const u8 hdr_md5 [ ] = {
0x30 , 0x20 , 0x30 , 0x0c , 0x06 , 0x08 , 0x2a , 0x86 , 0x48 , 0x86 , 0xf7 ,
0x0d , 0x02 , 0x05 , 0x05 , 0x00 , 0x04 , 0x10
} ;
static const u8 hdr_sha1 [ ] = {
0x30 , 0x21 , 0x30 , 0x09 , 0x06 , 0x05 , 0x2b , 0x0e , 0x03 , 0x02 , 0x1a ,
0x05 , 0x00 , 0x04 , 0x14
} ;
2007-02-02 22:15:14 +00:00
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
} ;
2003-07-15 10:49:28 +00:00
static const u8 hdr_ripemd160 [ ] = {
0x30 , 0x21 , 0x30 , 0x09 , 0x06 , 0x05 , 0x2b , 0x24 , 0x03 , 0x02 , 0x01 ,
0x05 , 0x00 , 0x04 , 0x14
} ;
static const struct digest_info_prefix {
unsigned int algorithm ;
const u8 * hdr ;
size_t hdr_len ;
size_t hash_len ;
2007-02-02 22:15:14 +00:00
} digest_info_prefix [ ] = {
2004-09-20 09:47:35 +00:00
{ SC_ALGORITHM_RSA_HASH_NONE , NULL , 0 , 0 } ,
2003-07-15 10:49:28 +00:00
{ SC_ALGORITHM_RSA_HASH_MD5 , hdr_md5 , sizeof ( hdr_md5 ) , 16 } ,
{ SC_ALGORITHM_RSA_HASH_SHA1 , hdr_sha1 , sizeof ( hdr_sha1 ) , 20 } ,
2007-02-02 22:15:14 +00:00
{ 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 } ,
2003-07-15 10:49:28 +00:00
{ SC_ALGORITHM_RSA_HASH_RIPEMD160 , hdr_ripemd160 , sizeof ( hdr_ripemd160 ) , 20 } ,
{ SC_ALGORITHM_RSA_HASH_MD5_SHA1 , NULL , 0 , 36 } ,
2004-09-20 09:47:35 +00:00
{ 0 , NULL , 0 , 0 }
2003-07-15 10:49:28 +00:00
} ;
/* add/remove pkcs1 BT01 padding */
2007-02-02 22:15:14 +00:00
static int sc_pkcs1_add_01_padding ( const u8 * in , size_t in_len ,
u8 * out , size_t * out_len , size_t mod_length )
2003-07-15 10:49:28 +00:00
{
size_t i ;
if ( * out_len < mod_length )
return SC_ERROR_BUFFER_TOO_SMALL ;
if ( in_len + 11 > mod_length )
return SC_ERROR_INVALID_ARGUMENTS ;
i = mod_length - in_len ;
memmove ( out + i , in , in_len ) ;
2005-04-04 21:52:31 +00:00
* out + + = 0x00 ;
2003-07-15 10:49:28 +00:00
* out + + = 0x01 ;
memset ( out , 0xFF , i - 3 ) ;
out + = i - 3 ;
* out = 0x00 ;
* out_len = mod_length ;
return SC_SUCCESS ;
}
2013-05-22 10:10:26 +00:00
int
sc_pkcs1_strip_01_padding ( struct sc_context * ctx , const u8 * in_dat , size_t in_len ,
u8 * out , size_t * out_len )
2003-07-15 10:49:28 +00:00
{
const u8 * tmp = in_dat ;
size_t len ;
if ( in_dat = = NULL | | in_len < 10 )
return SC_ERROR_INTERNAL ;
2007-02-02 22:15:14 +00:00
/* skip leading zero byte */
2003-07-15 10:49:28 +00:00
if ( * tmp = = 0 ) {
tmp + + ;
in_len - - ;
}
len = in_len ;
if ( * tmp ! = 0x01 )
return SC_ERROR_WRONG_PADDING ;
for ( tmp + + , len - - ; * tmp = = 0xff & & len ! = 0 ; tmp + + , len - - )
;
if ( ! len | | ( in_len - len ) < 9 | | * tmp + + ! = 0x00 )
return SC_ERROR_WRONG_PADDING ;
len - - ;
if ( out = = NULL )
/* just check the padding */
return SC_SUCCESS ;
if ( * out_len < len )
return SC_ERROR_INTERNAL ;
memmove ( out , tmp , len ) ;
* out_len = len ;
return SC_SUCCESS ;
}
2013-05-22 10:10:26 +00:00
2003-07-15 10:49:28 +00:00
/* remove pkcs1 BT02 padding (adding BT02 padding is currently not
* needed / implemented ) */
2013-05-22 10:10:26 +00:00
int
sc_pkcs1_strip_02_padding ( sc_context_t * ctx , const u8 * data , size_t len , u8 * out , size_t * out_len )
2003-07-15 10:49:28 +00:00
{
unsigned int n = 0 ;
2013-05-22 10:10:26 +00:00
LOG_FUNC_CALLED ( ctx ) ;
2003-07-15 10:49:28 +00:00
if ( data = = NULL | | len < 3 )
2013-05-22 10:10:26 +00:00
LOG_FUNC_RETURN ( ctx , SC_ERROR_INTERNAL ) ;
2007-02-02 22:15:14 +00:00
/* skip leading zero byte */
2003-07-15 10:49:28 +00:00
if ( * data = = 0 ) {
data + + ;
len - - ;
}
if ( data [ 0 ] ! = 0x02 )
2013-05-22 10:10:26 +00:00
LOG_FUNC_RETURN ( ctx , SC_ERROR_WRONG_PADDING ) ;
2003-07-15 10:49:28 +00:00
/* skip over padding bytes */
for ( n = 1 ; n < len & & data [ n ] ; n + + )
;
/* Must be at least 8 pad bytes */
if ( n > = len | | n < 9 )
2013-05-22 10:10:26 +00:00
LOG_FUNC_RETURN ( ctx , SC_ERROR_WRONG_PADDING ) ;
2003-07-15 10:49:28 +00:00
n + + ;
if ( out = = NULL )
/* just check the padding */
2013-05-22 10:10:26 +00:00
LOG_FUNC_RETURN ( ctx , SC_SUCCESS ) ;
2003-07-15 10:49:28 +00:00
/* Now move decrypted contents to head of buffer */
2013-09-24 16:00:49 +00:00
if ( * out_len < len - n )
2013-05-22 10:10:26 +00:00
LOG_FUNC_RETURN ( ctx , SC_ERROR_INTERNAL ) ;
2013-09-24 16:00:49 +00:00
* out_len = len - n ;
memmove ( out , data + n , * out_len ) ;
2013-05-22 10:10:26 +00:00
2017-03-14 19:02:30 +00:00
sc_log ( ctx , " stripped output(% " SC_FORMAT_LEN_SIZE_T " u): %s " , len - n ,
sc_dump_hex ( out , len - n ) ) ;
2013-05-22 10:10:26 +00:00
LOG_FUNC_RETURN ( ctx , len - n ) ;
2003-07-15 10:49:28 +00:00
}
/* add/remove DigestInfo prefix */
2007-02-02 22:15:14 +00:00
static int sc_pkcs1_add_digest_info_prefix ( unsigned int algorithm ,
const u8 * in , size_t in_len , u8 * out , size_t * out_len )
2003-07-15 10:49:28 +00:00
{
int i ;
2007-02-02 22:15:14 +00:00
for ( i = 0 ; digest_info_prefix [ i ] . algorithm ! = 0 ; i + + ) {
2003-07-15 10:49:28 +00:00
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 ,
hash_len = digest_info_prefix [ i ] . hash_len ;
2011-03-13 18:11:07 +00:00
if ( in_len ! = hash_len | | * out_len < ( hdr_len + hash_len ) )
2003-07-15 10:49:28 +00:00
return SC_ERROR_INTERNAL ;
2011-03-13 18:11:07 +00:00
2003-07-15 10:49:28 +00:00
memmove ( out + hdr_len , in , hash_len ) ;
memmove ( out , hdr , hdr_len ) ;
* out_len = hdr_len + hash_len ;
2011-03-13 18:11:07 +00:00
2003-07-15 10:49:28 +00:00
return SC_SUCCESS ;
}
}
return SC_ERROR_INTERNAL ;
}
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 )
{
int i ;
2007-02-02 22:15:14 +00:00
for ( i = 0 ; digest_info_prefix [ i ] . algorithm ! = 0 ; i + + ) {
2003-07-15 10:49:28 +00:00
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 ;
if ( in_len = = ( hdr_len + hash_len ) & &
! memcmp ( in_dat , hdr , hdr_len ) ) {
if ( algorithm )
* algorithm = digest_info_prefix [ i ] . algorithm ;
if ( out_dat = = NULL )
/* just check the DigestInfo prefix */
return SC_SUCCESS ;
if ( * out_len < hash_len )
return SC_ERROR_INTERNAL ;
memmove ( out_dat , in_dat + hdr_len , hash_len ) ;
* out_len = hash_len ;
return SC_SUCCESS ;
}
}
return SC_ERROR_INTERNAL ;
}
Add support for PSS padding to RSA signatures
A card driver may declare support for computing the padding on the card,
or else the padding will be applied locally in padding.c. All five
PKCS11 PSS mechanisms are supported, for signature and verification.
There are a few limits on what we choose to support, in particular I
don't see a need for arbitrary combinations of MGF hash, data hash, and
salt length, so I've restricted it (for the user's benefit) to the only
cases that really matter, where salt_len = hash_len and the same hash is
used for the MGF and data hashing.
------------------------------------------------------------------------
Reworked and extended in 2018 by Jakub Jelen <jjelen@redhat.com> against
current OpenSC master, to actually work with existing PIV cards:
* extended of missing mechanisms (SHA224, possibility to select MGF1)
* compatibility with OpenSSL 1.1+
* Removed the ANSI padding
* Formatting cleanup, error checking
Based on the original work from
https://github.com/NWilson/OpenSC/commit/42f3199e66
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2015-08-25 11:45:27 +00:00
# ifdef ENABLE_OPENSSL
static const EVP_MD * hash_flag2md ( unsigned int hash )
{
switch ( hash & SC_ALGORITHM_RSA_HASHES ) {
case SC_ALGORITHM_RSA_HASH_SHA1 :
return EVP_sha1 ( ) ;
case SC_ALGORITHM_RSA_HASH_SHA224 :
return EVP_sha224 ( ) ;
case SC_ALGORITHM_RSA_HASH_SHA256 :
return EVP_sha256 ( ) ;
case SC_ALGORITHM_RSA_HASH_SHA384 :
return EVP_sha384 ( ) ;
case SC_ALGORITHM_RSA_HASH_SHA512 :
return EVP_sha512 ( ) ;
default :
return NULL ;
}
}
static const EVP_MD * mgf1_flag2md ( unsigned int mgf1 )
{
switch ( mgf1 & SC_ALGORITHM_MGF1_HASHES ) {
case SC_ALGORITHM_MGF1_SHA1 :
return EVP_sha1 ( ) ;
case SC_ALGORITHM_MGF1_SHA224 :
return EVP_sha224 ( ) ;
case SC_ALGORITHM_MGF1_SHA256 :
return EVP_sha256 ( ) ;
case SC_ALGORITHM_MGF1_SHA384 :
return EVP_sha384 ( ) ;
case SC_ALGORITHM_MGF1_SHA512 :
return EVP_sha512 ( ) ;
default :
return NULL ;
}
}
/* add PKCS#1 v2.0 PSS padding */
static int sc_pkcs1_add_pss_padding ( unsigned int hash , unsigned int mgf1_hash ,
const u8 * in , size_t in_len , u8 * out , size_t * out_len , size_t mod_bits )
{
/* hLen = sLen in our case */
int rv = SC_ERROR_INTERNAL , i , j , hlen , dblen , plen , round , mgf_rounds ;
int mgf1_hlen ;
const EVP_MD * md , * mgf1_md ;
EVP_MD_CTX * ctx = NULL ;
u8 buf [ 8 ] ;
u8 salt [ EVP_MAX_MD_SIZE ] , mask [ EVP_MAX_MD_SIZE ] ;
size_t mod_length = ( mod_bits + 7 ) / 8 ;
if ( * out_len < mod_length )
return SC_ERROR_BUFFER_TOO_SMALL ;
md = hash_flag2md ( hash ) ;
if ( md = = NULL )
return SC_ERROR_NOT_SUPPORTED ;
hlen = EVP_MD_size ( md ) ;
dblen = mod_length - hlen - 1 ; /* emLen - hLen - 1 */
plen = mod_length - 2 * hlen - 1 ;
if ( in_len ! = ( unsigned ) hlen )
return SC_ERROR_INVALID_ARGUMENTS ;
if ( 2 * ( unsigned ) hlen + 2 > mod_length )
/* RSA key too small for chosen hash (1296 bits or higher needed for
* signing SHA - 512 hashes ) */
return SC_ERROR_NOT_SUPPORTED ;
if ( RAND_bytes ( salt , hlen ) ! = 1 )
return SC_ERROR_INTERNAL ;
/* Hash M' to create H */
if ( ! ( ctx = EVP_MD_CTX_create ( ) ) )
goto done ;
memset ( buf , 0x00 , 8 ) ;
if ( EVP_DigestInit_ex ( ctx , md , NULL ) ! = 1 | |
EVP_DigestUpdate ( ctx , buf , 8 ) ! = 1 | |
EVP_DigestUpdate ( ctx , in , hlen ) ! = 1 | | /* mHash */
EVP_DigestUpdate ( ctx , salt , hlen ) ! = 1 ) {
goto done ;
}
/* Construct padding2, salt, H, and BC in the output block */
/* DB = PS || 0x01 || salt */
memset ( out , 0x00 , plen - 1 ) ; /* emLen - sLen - hLen - 2 */
out [ plen - 1 ] = 0x01 ;
memcpy ( out + plen , salt , hlen ) ;
if ( EVP_DigestFinal_ex ( ctx , out + dblen , NULL ) ! = 1 ) { /* H */
goto done ;
}
out [ dblen + hlen ] = 0xBC ;
/* EM = DB* || H || 0xbc
* * the first part is masked later */
/* Construct the DB mask block by block and XOR it in. */
mgf1_md = mgf1_flag2md ( mgf1_hash ) ;
if ( mgf1_md = = NULL )
return SC_ERROR_NOT_SUPPORTED ;
mgf1_hlen = EVP_MD_size ( mgf1_md ) ;
mgf_rounds = ( dblen + mgf1_hlen - 1 ) / mgf1_hlen ; /* round up */
for ( round = 0 ; round < mgf_rounds ; + + round ) {
buf [ 0 ] = ( round & 0xFF000000U ) > > 24 ;
buf [ 1 ] = ( round & 0x00FF0000U ) > > 16 ;
buf [ 2 ] = ( round & 0x0000FF00U ) > > 8 ;
buf [ 3 ] = ( round & 0x000000FFU ) ;
if ( EVP_DigestInit_ex ( ctx , mgf1_md , NULL ) ! = 1 | |
EVP_DigestUpdate ( ctx , out + dblen , hlen ) ! = 1 | | /* H (Z parameter of MGF1) */
EVP_DigestUpdate ( ctx , buf , 4 ) ! = 1 | | /* C */
2018-10-31 16:50:08 +00:00
EVP_DigestFinal_ex ( ctx , mask , NULL ) ! = 1 ) {
Add support for PSS padding to RSA signatures
A card driver may declare support for computing the padding on the card,
or else the padding will be applied locally in padding.c. All five
PKCS11 PSS mechanisms are supported, for signature and verification.
There are a few limits on what we choose to support, in particular I
don't see a need for arbitrary combinations of MGF hash, data hash, and
salt length, so I've restricted it (for the user's benefit) to the only
cases that really matter, where salt_len = hash_len and the same hash is
used for the MGF and data hashing.
------------------------------------------------------------------------
Reworked and extended in 2018 by Jakub Jelen <jjelen@redhat.com> against
current OpenSC master, to actually work with existing PIV cards:
* extended of missing mechanisms (SHA224, possibility to select MGF1)
* compatibility with OpenSSL 1.1+
* Removed the ANSI padding
* Formatting cleanup, error checking
Based on the original work from
https://github.com/NWilson/OpenSC/commit/42f3199e66
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2015-08-25 11:45:27 +00:00
goto done ;
}
/* this is no longer part of the MGF1, but actually
* XORing mask with DB to create maskedDB inplace */
for ( i = round * mgf1_hlen , j = 0 ; i < dblen & & j < mgf1_hlen ; + + i , + + j ) {
out [ i ] ^ = mask [ j ] ;
}
}
/* Set leftmost N bits in leftmost octet in maskedDB to zero
* to make sure the result is smaller than the modulus ( + 1 )
*/
out [ 0 ] & = ( 0xff > > ( 8 * mod_length - mod_bits + 1 ) ) ;
* out_len = mod_length ;
rv = SC_SUCCESS ;
done :
OPENSSL_cleanse ( salt , sizeof ( salt ) ) ;
OPENSSL_cleanse ( mask , sizeof ( mask ) ) ;
if ( ctx ) {
EVP_MD_CTX_destroy ( ctx ) ;
}
return rv ;
}
static int hash_len2algo ( size_t hash_len )
{
switch ( hash_len ) {
case SHA_DIGEST_LENGTH :
return SC_ALGORITHM_RSA_HASH_SHA1 ;
case SHA224_DIGEST_LENGTH :
return SC_ALGORITHM_RSA_HASH_SHA224 ;
case SHA256_DIGEST_LENGTH :
return SC_ALGORITHM_RSA_HASH_SHA256 ;
case SHA384_DIGEST_LENGTH :
return SC_ALGORITHM_RSA_HASH_SHA384 ;
case SHA512_DIGEST_LENGTH :
return SC_ALGORITHM_RSA_HASH_SHA512 ;
}
/* Should never happen -- the mechanism and data should be already
* verified to match one of the above . If not , we will fail later
*/
return SC_ALGORITHM_RSA_HASH_NONE ;
}
# endif
2003-07-15 10:49:28 +00:00
/* general PKCS#1 encoding function */
2005-03-08 20:59:35 +00:00
int sc_pkcs1_encode ( sc_context_t * ctx , unsigned long flags ,
Add support for PSS padding to RSA signatures
A card driver may declare support for computing the padding on the card,
or else the padding will be applied locally in padding.c. All five
PKCS11 PSS mechanisms are supported, for signature and verification.
There are a few limits on what we choose to support, in particular I
don't see a need for arbitrary combinations of MGF hash, data hash, and
salt length, so I've restricted it (for the user's benefit) to the only
cases that really matter, where salt_len = hash_len and the same hash is
used for the MGF and data hashing.
------------------------------------------------------------------------
Reworked and extended in 2018 by Jakub Jelen <jjelen@redhat.com> against
current OpenSC master, to actually work with existing PIV cards:
* extended of missing mechanisms (SHA224, possibility to select MGF1)
* compatibility with OpenSSL 1.1+
* Removed the ANSI padding
* Formatting cleanup, error checking
Based on the original work from
https://github.com/NWilson/OpenSC/commit/42f3199e66
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2015-08-25 11:45:27 +00:00
const u8 * in , size_t in_len , u8 * out , size_t * out_len , size_t mod_bits )
2003-07-15 10:49:28 +00:00
{
2011-03-13 18:11:07 +00:00
int rv , i ;
2003-07-15 10:49:28 +00:00
size_t tmp_len = * out_len ;
const u8 * tmp = in ;
unsigned int hash_algo , pad_algo ;
Add support for PSS padding to RSA signatures
A card driver may declare support for computing the padding on the card,
or else the padding will be applied locally in padding.c. All five
PKCS11 PSS mechanisms are supported, for signature and verification.
There are a few limits on what we choose to support, in particular I
don't see a need for arbitrary combinations of MGF hash, data hash, and
salt length, so I've restricted it (for the user's benefit) to the only
cases that really matter, where salt_len = hash_len and the same hash is
used for the MGF and data hashing.
------------------------------------------------------------------------
Reworked and extended in 2018 by Jakub Jelen <jjelen@redhat.com> against
current OpenSC master, to actually work with existing PIV cards:
* extended of missing mechanisms (SHA224, possibility to select MGF1)
* compatibility with OpenSSL 1.1+
* Removed the ANSI padding
* Formatting cleanup, error checking
Based on the original work from
https://github.com/NWilson/OpenSC/commit/42f3199e66
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2015-08-25 11:45:27 +00:00
size_t mod_len = ( mod_bits + 7 ) / 8 ;
# ifdef ENABLE_OPENSSL
unsigned int mgf1_hash ;
# endif
2003-07-15 10:49:28 +00:00
2011-03-13 18:11:07 +00:00
LOG_FUNC_CALLED ( ctx ) ;
Add support for PSS padding to RSA signatures
A card driver may declare support for computing the padding on the card,
or else the padding will be applied locally in padding.c. All five
PKCS11 PSS mechanisms are supported, for signature and verification.
There are a few limits on what we choose to support, in particular I
don't see a need for arbitrary combinations of MGF hash, data hash, and
salt length, so I've restricted it (for the user's benefit) to the only
cases that really matter, where salt_len = hash_len and the same hash is
used for the MGF and data hashing.
------------------------------------------------------------------------
Reworked and extended in 2018 by Jakub Jelen <jjelen@redhat.com> against
current OpenSC master, to actually work with existing PIV cards:
* extended of missing mechanisms (SHA224, possibility to select MGF1)
* compatibility with OpenSSL 1.1+
* Removed the ANSI padding
* Formatting cleanup, error checking
Based on the original work from
https://github.com/NWilson/OpenSC/commit/42f3199e66
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2015-08-25 11:45:27 +00:00
hash_algo = flags & SC_ALGORITHM_RSA_HASHES ;
2003-07-15 10:49:28 +00:00
pad_algo = flags & SC_ALGORITHM_RSA_PADS ;
2011-03-13 18:11:07 +00:00
sc_log ( ctx , " hash algorithm 0x%X, pad algorithm 0x%X " , hash_algo , pad_algo ) ;
2003-07-15 10:49:28 +00:00
2018-10-11 09:22:15 +00:00
if ( ( pad_algo = = SC_ALGORITHM_RSA_PAD_PKCS1 | | pad_algo = = SC_ALGORITHM_RSA_PAD_NONE ) & &
Add support for PSS padding to RSA signatures
A card driver may declare support for computing the padding on the card,
or else the padding will be applied locally in padding.c. All five
PKCS11 PSS mechanisms are supported, for signature and verification.
There are a few limits on what we choose to support, in particular I
don't see a need for arbitrary combinations of MGF hash, data hash, and
salt length, so I've restricted it (for the user's benefit) to the only
cases that really matter, where salt_len = hash_len and the same hash is
used for the MGF and data hashing.
------------------------------------------------------------------------
Reworked and extended in 2018 by Jakub Jelen <jjelen@redhat.com> against
current OpenSC master, to actually work with existing PIV cards:
* extended of missing mechanisms (SHA224, possibility to select MGF1)
* compatibility with OpenSSL 1.1+
* Removed the ANSI padding
* Formatting cleanup, error checking
Based on the original work from
https://github.com/NWilson/OpenSC/commit/42f3199e66
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2015-08-25 11:45:27 +00:00
hash_algo ! = SC_ALGORITHM_RSA_HASH_NONE ) {
2011-03-13 18:11:07 +00:00
i = sc_pkcs1_add_digest_info_prefix ( hash_algo , in , in_len , out , & tmp_len ) ;
2003-07-15 10:49:28 +00:00
if ( i ! = SC_SUCCESS ) {
2011-03-13 18:11:07 +00:00
sc_log ( ctx , " Unable to add digest info 0x%x " , hash_algo ) ;
LOG_FUNC_RETURN ( ctx , i ) ;
2003-07-15 10:49:28 +00:00
}
tmp = out ;
2011-03-13 18:11:07 +00:00
} else {
2003-07-15 10:49:28 +00:00
tmp_len = in_len ;
2011-03-13 18:11:07 +00:00
}
2003-07-15 10:49:28 +00:00
switch ( pad_algo ) {
case SC_ALGORITHM_RSA_PAD_NONE :
/* padding done by card => nothing to do */
2004-12-13 20:58:28 +00:00
if ( out ! = tmp )
memcpy ( out , tmp , tmp_len ) ;
2003-07-15 10:49:28 +00:00
* out_len = tmp_len ;
2011-03-13 18:11:07 +00:00
LOG_FUNC_RETURN ( ctx , SC_SUCCESS ) ;
2003-07-15 10:49:28 +00:00
case SC_ALGORITHM_RSA_PAD_PKCS1 :
/* add pkcs1 bt01 padding */
2011-03-13 18:11:07 +00:00
rv = sc_pkcs1_add_01_padding ( tmp , tmp_len , out , out_len , mod_len ) ;
LOG_FUNC_RETURN ( ctx , rv ) ;
Add support for PSS padding to RSA signatures
A card driver may declare support for computing the padding on the card,
or else the padding will be applied locally in padding.c. All five
PKCS11 PSS mechanisms are supported, for signature and verification.
There are a few limits on what we choose to support, in particular I
don't see a need for arbitrary combinations of MGF hash, data hash, and
salt length, so I've restricted it (for the user's benefit) to the only
cases that really matter, where salt_len = hash_len and the same hash is
used for the MGF and data hashing.
------------------------------------------------------------------------
Reworked and extended in 2018 by Jakub Jelen <jjelen@redhat.com> against
current OpenSC master, to actually work with existing PIV cards:
* extended of missing mechanisms (SHA224, possibility to select MGF1)
* compatibility with OpenSSL 1.1+
* Removed the ANSI padding
* Formatting cleanup, error checking
Based on the original work from
https://github.com/NWilson/OpenSC/commit/42f3199e66
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2015-08-25 11:45:27 +00:00
case SC_ALGORITHM_RSA_PAD_PSS :
/* add PSS padding */
# ifdef ENABLE_OPENSSL
mgf1_hash = flags & SC_ALGORITHM_MGF1_HASHES ;
if ( hash_algo = = SC_ALGORITHM_RSA_HASH_NONE ) {
/* this is generic RSA_PKCS1_PSS mechanism with hash
* already done outside of the module . The parameters
* were already checked so we need to adjust the hash
* algorithm to do the padding with the correct hash
* function .
*/
hash_algo = hash_len2algo ( tmp_len ) ;
}
rv = sc_pkcs1_add_pss_padding ( hash_algo , mgf1_hash ,
tmp , tmp_len , out , out_len , mod_bits ) ;
# else
rv = SC_ERROR_NOT_SUPPORTED ;
# endif
LOG_FUNC_RETURN ( ctx , rv ) ;
2003-07-15 10:49:28 +00:00
default :
Add support for PSS padding to RSA signatures
A card driver may declare support for computing the padding on the card,
or else the padding will be applied locally in padding.c. All five
PKCS11 PSS mechanisms are supported, for signature and verification.
There are a few limits on what we choose to support, in particular I
don't see a need for arbitrary combinations of MGF hash, data hash, and
salt length, so I've restricted it (for the user's benefit) to the only
cases that really matter, where salt_len = hash_len and the same hash is
used for the MGF and data hashing.
------------------------------------------------------------------------
Reworked and extended in 2018 by Jakub Jelen <jjelen@redhat.com> against
current OpenSC master, to actually work with existing PIV cards:
* extended of missing mechanisms (SHA224, possibility to select MGF1)
* compatibility with OpenSSL 1.1+
* Removed the ANSI padding
* Formatting cleanup, error checking
Based on the original work from
https://github.com/NWilson/OpenSC/commit/42f3199e66
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2015-08-25 11:45:27 +00:00
/* We shouldn't be called with an unexpected padding type, we've already
* returned SC_ERROR_NOT_SUPPORTED if the card can ' t be used . */
LOG_FUNC_RETURN ( ctx , SC_ERROR_INTERNAL ) ;
2003-07-15 10:49:28 +00:00
}
}
2007-02-02 22:15:14 +00:00
int sc_get_encoding_flags ( sc_context_t * ctx ,
unsigned long iflags , unsigned long caps ,
unsigned long * pflags , unsigned long * sflags )
2003-07-15 10:49:28 +00:00
{
2011-03-13 18:11:07 +00:00
LOG_FUNC_CALLED ( ctx ) ;
2007-02-02 22:15:14 +00:00
if ( pflags = = NULL | | sflags = = NULL )
2011-03-13 18:11:07 +00:00
LOG_FUNC_RETURN ( ctx , SC_ERROR_INVALID_ARGUMENTS ) ;
2007-02-02 22:15:14 +00:00
2017-03-14 19:02:30 +00:00
sc_log ( ctx , " iFlags 0x%lX, card capabilities 0x%lX " , iflags , caps ) ;
2003-07-15 10:49:28 +00:00
Add support for PSS padding to RSA signatures
A card driver may declare support for computing the padding on the card,
or else the padding will be applied locally in padding.c. All five
PKCS11 PSS mechanisms are supported, for signature and verification.
There are a few limits on what we choose to support, in particular I
don't see a need for arbitrary combinations of MGF hash, data hash, and
salt length, so I've restricted it (for the user's benefit) to the only
cases that really matter, where salt_len = hash_len and the same hash is
used for the MGF and data hashing.
------------------------------------------------------------------------
Reworked and extended in 2018 by Jakub Jelen <jjelen@redhat.com> against
current OpenSC master, to actually work with existing PIV cards:
* extended of missing mechanisms (SHA224, possibility to select MGF1)
* compatibility with OpenSSL 1.1+
* Removed the ANSI padding
* Formatting cleanup, error checking
Based on the original work from
https://github.com/NWilson/OpenSC/commit/42f3199e66
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2015-08-25 11:45:27 +00:00
/* For ECDSA and GOSTR, we don't do any padding or hashing ourselves, the
* card has to support the requested operation . Similarly , for RSA with
* raw padding ( raw RSA ) and ISO9796 , we require the card to do it for us .
* Finally , for PKCS1 ( v1 .5 and PSS ) and ASNI X9 .31 we can apply the padding
* ourselves if the card supports raw RSA . */
2011-03-13 18:11:07 +00:00
Add support for PSS padding to RSA signatures
A card driver may declare support for computing the padding on the card,
or else the padding will be applied locally in padding.c. All five
PKCS11 PSS mechanisms are supported, for signature and verification.
There are a few limits on what we choose to support, in particular I
don't see a need for arbitrary combinations of MGF hash, data hash, and
salt length, so I've restricted it (for the user's benefit) to the only
cases that really matter, where salt_len = hash_len and the same hash is
used for the MGF and data hashing.
------------------------------------------------------------------------
Reworked and extended in 2018 by Jakub Jelen <jjelen@redhat.com> against
current OpenSC master, to actually work with existing PIV cards:
* extended of missing mechanisms (SHA224, possibility to select MGF1)
* compatibility with OpenSSL 1.1+
* Removed the ANSI padding
* Formatting cleanup, error checking
Based on the original work from
https://github.com/NWilson/OpenSC/commit/42f3199e66
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2015-08-25 11:45:27 +00:00
/* TODO: Could convert GOSTR3410_HASH_GOSTR3411 -> GOSTR3410_RAW and
* ECDSA_HASH_ - > ECDSA_RAW using OpenSSL ( not much benefit though ) . */
if ( ( caps & iflags ) = = iflags ) {
/* Card supports the signature operation we want to do, great, let's
* go with it then . */
* sflags = iflags ;
2007-02-02 22:15:14 +00:00
* pflags = 0 ;
Add support for PSS padding to RSA signatures
A card driver may declare support for computing the padding on the card,
or else the padding will be applied locally in padding.c. All five
PKCS11 PSS mechanisms are supported, for signature and verification.
There are a few limits on what we choose to support, in particular I
don't see a need for arbitrary combinations of MGF hash, data hash, and
salt length, so I've restricted it (for the user's benefit) to the only
cases that really matter, where salt_len = hash_len and the same hash is
used for the MGF and data hashing.
------------------------------------------------------------------------
Reworked and extended in 2018 by Jakub Jelen <jjelen@redhat.com> against
current OpenSC master, to actually work with existing PIV cards:
* extended of missing mechanisms (SHA224, possibility to select MGF1)
* compatibility with OpenSSL 1.1+
* Removed the ANSI padding
* Formatting cleanup, error checking
Based on the original work from
https://github.com/NWilson/OpenSC/commit/42f3199e66
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2015-08-25 11:45:27 +00:00
} else if ( ( caps & SC_ALGORITHM_RSA_PAD_PSS ) & &
2018-10-04 13:59:11 +00:00
( iflags & SC_ALGORITHM_RSA_PAD_PSS ) ) {
Add support for PSS padding to RSA signatures
A card driver may declare support for computing the padding on the card,
or else the padding will be applied locally in padding.c. All five
PKCS11 PSS mechanisms are supported, for signature and verification.
There are a few limits on what we choose to support, in particular I
don't see a need for arbitrary combinations of MGF hash, data hash, and
salt length, so I've restricted it (for the user's benefit) to the only
cases that really matter, where salt_len = hash_len and the same hash is
used for the MGF and data hashing.
------------------------------------------------------------------------
Reworked and extended in 2018 by Jakub Jelen <jjelen@redhat.com> against
current OpenSC master, to actually work with existing PIV cards:
* extended of missing mechanisms (SHA224, possibility to select MGF1)
* compatibility with OpenSSL 1.1+
* Removed the ANSI padding
* Formatting cleanup, error checking
Based on the original work from
https://github.com/NWilson/OpenSC/commit/42f3199e66
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2015-08-25 11:45:27 +00:00
* sflags | = SC_ALGORITHM_RSA_PAD_PSS ;
} else if ( ( ( caps & SC_ALGORITHM_RSA_RAW ) & &
2018-10-04 13:59:11 +00:00
( iflags & SC_ALGORITHM_RSA_PAD_PKCS1 ) )
| | iflags & SC_ALGORITHM_RSA_PAD_PSS
| | iflags & SC_ALGORITHM_RSA_PAD_NONE ) {
Add support for PSS padding to RSA signatures
A card driver may declare support for computing the padding on the card,
or else the padding will be applied locally in padding.c. All five
PKCS11 PSS mechanisms are supported, for signature and verification.
There are a few limits on what we choose to support, in particular I
don't see a need for arbitrary combinations of MGF hash, data hash, and
salt length, so I've restricted it (for the user's benefit) to the only
cases that really matter, where salt_len = hash_len and the same hash is
used for the MGF and data hashing.
------------------------------------------------------------------------
Reworked and extended in 2018 by Jakub Jelen <jjelen@redhat.com> against
current OpenSC master, to actually work with existing PIV cards:
* extended of missing mechanisms (SHA224, possibility to select MGF1)
* compatibility with OpenSSL 1.1+
* Removed the ANSI padding
* Formatting cleanup, error checking
Based on the original work from
https://github.com/NWilson/OpenSC/commit/42f3199e66
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2015-08-25 11:45:27 +00:00
/* Use the card's raw RSA capability on the padded input */
* sflags = SC_ALGORITHM_RSA_PAD_NONE ;
* pflags = iflags ;
} else if ( ( caps & ( SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE ) ) & &
2018-10-04 13:59:11 +00:00
( iflags & SC_ALGORITHM_RSA_PAD_PKCS1 ) ) {
Add support for PSS padding to RSA signatures
A card driver may declare support for computing the padding on the card,
or else the padding will be applied locally in padding.c. All five
PKCS11 PSS mechanisms are supported, for signature and verification.
There are a few limits on what we choose to support, in particular I
don't see a need for arbitrary combinations of MGF hash, data hash, and
salt length, so I've restricted it (for the user's benefit) to the only
cases that really matter, where salt_len = hash_len and the same hash is
used for the MGF and data hashing.
------------------------------------------------------------------------
Reworked and extended in 2018 by Jakub Jelen <jjelen@redhat.com> against
current OpenSC master, to actually work with existing PIV cards:
* extended of missing mechanisms (SHA224, possibility to select MGF1)
* compatibility with OpenSSL 1.1+
* Removed the ANSI padding
* Formatting cleanup, error checking
Based on the original work from
https://github.com/NWilson/OpenSC/commit/42f3199e66
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
2015-08-25 11:45:27 +00:00
/* A corner case - the card can partially do PKCS1, if we prepend the
* DigestInfo bit it will do the rest . */
* sflags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE ;
* pflags = iflags & SC_ALGORITHM_RSA_HASHES ;
2018-10-18 13:56:06 +00:00
} else if ( ( iflags & SC_ALGORITHM_AES ) = = SC_ALGORITHM_AES ) { /* TODO: seems like this constant does not belong to the same set of flags used form asymmetric algos. Fix this! */
2017-11-17 13:51:48 +00:00
* sflags = 0 ;
* pflags = 0 ;
} else if ( ( iflags & SC_ALGORITHM_AES_FLAGS ) > 0 ) {
* sflags = iflags & SC_ALGORITHM_AES_FLAGS ;
if ( iflags & SC_ALGORITHM_AES_CBC_PAD )
* pflags = SC_ALGORITHM_AES_CBC_PAD ;
else
* pflags = 0 ;
2007-02-02 22:15:14 +00:00
} else {
2011-03-13 18:11:07 +00:00
LOG_TEST_RET ( ctx , SC_ERROR_NOT_SUPPORTED , " unsupported algorithm " ) ;
2007-02-02 22:15:14 +00:00
}
2003-07-15 10:49:28 +00:00
2017-03-14 19:02:30 +00:00
sc_log ( ctx , " pad flags 0x%lX, secure algorithm flags 0x%lX " , * pflags , * sflags ) ;
2011-03-13 18:11:07 +00:00
LOG_FUNC_RETURN ( ctx , SC_SUCCESS ) ;
2003-07-15 10:49:28 +00:00
}