2015-06-16 20:31:01 +03:00
/*
* RSA key extract helper
*
* Copyright ( c ) 2015 , Intel Corporation
* Authors : Tadeusz Struk < tadeusz . struk @ intel . com >
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation ; either version 2 of the License , or ( at your option )
* any later version .
*
*/
# include <linux/kernel.h>
# include <linux/export.h>
# include <linux/err.h>
# include <linux/fips.h>
# include <crypto/internal/rsa.h>
2015-10-08 19:26:55 +03:00
# include "rsapubkey-asn1.h"
# include "rsaprivkey-asn1.h"
2015-06-16 20:31:01 +03:00
int rsa_get_n ( void * context , size_t hdrlen , unsigned char tag ,
const void * value , size_t vlen )
{
struct rsa_key * key = context ;
2016-06-14 16:14:58 +03:00
const u8 * ptr = value ;
size_t n_sz = vlen ;
2015-06-16 20:31:01 +03:00
2016-06-14 16:14:58 +03:00
/* invalid key provided */
if ( ! value | | ! vlen )
2015-06-16 20:31:01 +03:00
return - EINVAL ;
2016-06-14 16:14:58 +03:00
if ( fips_enabled ) {
2017-11-27 10:16:49 +03:00
while ( n_sz & & ! * ptr ) {
2016-06-14 16:14:58 +03:00
ptr + + ;
n_sz - - ;
}
2016-08-23 11:09:32 +03:00
/* In FIPS mode only allow key size 2K and higher */
if ( n_sz < 256 ) {
2016-06-14 16:14:58 +03:00
pr_err ( " RSA: key size not allowed in FIPS mode \n " ) ;
return - EINVAL ;
}
2015-06-16 20:31:01 +03:00
}
2016-06-14 16:14:58 +03:00
key - > n = value ;
key - > n_sz = vlen ;
2015-06-16 20:31:01 +03:00
return 0 ;
}
int rsa_get_e ( void * context , size_t hdrlen , unsigned char tag ,
const void * value , size_t vlen )
{
struct rsa_key * key = context ;
2016-06-14 16:14:58 +03:00
/* invalid key provided */
if ( ! value | | ! key - > n_sz | | ! vlen | | vlen > key - > n_sz )
return - EINVAL ;
2015-06-16 20:31:01 +03:00
2016-06-14 16:14:58 +03:00
key - > e = value ;
key - > e_sz = vlen ;
2015-06-16 20:31:01 +03:00
return 0 ;
}
int rsa_get_d ( void * context , size_t hdrlen , unsigned char tag ,
const void * value , size_t vlen )
{
struct rsa_key * key = context ;
2016-06-14 16:14:58 +03:00
/* invalid key provided */
if ( ! value | | ! key - > n_sz | | ! vlen | | vlen > key - > n_sz )
2015-06-16 20:31:01 +03:00
return - EINVAL ;
2016-06-14 16:14:58 +03:00
key - > d = value ;
key - > d_sz = vlen ;
2015-06-16 20:31:01 +03:00
2016-06-14 16:14:58 +03:00
return 0 ;
2015-06-16 20:31:01 +03:00
}
2016-07-04 19:21:38 +03:00
int rsa_get_p ( void * context , size_t hdrlen , unsigned char tag ,
const void * value , size_t vlen )
{
struct rsa_key * key = context ;
/* invalid key provided */
if ( ! value | | ! vlen | | vlen > key - > n_sz )
return - EINVAL ;
key - > p = value ;
key - > p_sz = vlen ;
return 0 ;
}
int rsa_get_q ( void * context , size_t hdrlen , unsigned char tag ,
const void * value , size_t vlen )
{
struct rsa_key * key = context ;
/* invalid key provided */
if ( ! value | | ! vlen | | vlen > key - > n_sz )
return - EINVAL ;
key - > q = value ;
key - > q_sz = vlen ;
return 0 ;
}
int rsa_get_dp ( void * context , size_t hdrlen , unsigned char tag ,
const void * value , size_t vlen )
{
struct rsa_key * key = context ;
/* invalid key provided */
if ( ! value | | ! vlen | | vlen > key - > n_sz )
return - EINVAL ;
key - > dp = value ;
key - > dp_sz = vlen ;
return 0 ;
}
int rsa_get_dq ( void * context , size_t hdrlen , unsigned char tag ,
const void * value , size_t vlen )
{
struct rsa_key * key = context ;
/* invalid key provided */
if ( ! value | | ! vlen | | vlen > key - > n_sz )
return - EINVAL ;
key - > dq = value ;
key - > dq_sz = vlen ;
return 0 ;
}
int rsa_get_qinv ( void * context , size_t hdrlen , unsigned char tag ,
const void * value , size_t vlen )
{
struct rsa_key * key = context ;
/* invalid key provided */
if ( ! value | | ! vlen | | vlen > key - > n_sz )
return - EINVAL ;
key - > qinv = value ;
key - > qinv_sz = vlen ;
return 0 ;
}
2015-06-16 20:31:01 +03:00
/**
2016-06-14 16:14:58 +03:00
* rsa_parse_pub_key ( ) - decodes the BER encoded buffer and stores in the
* provided struct rsa_key , pointers to the raw key as is ,
* so that the caller can copy it or MPI parse it , etc .
2015-06-16 20:31:01 +03:00
*
* @ rsa_key : struct rsa_key key representation
* @ key : key in BER format
* @ key_len : length of key
*
* Return : 0 on success or error code in case of error
*/
2015-10-08 19:26:55 +03:00
int rsa_parse_pub_key ( struct rsa_key * rsa_key , const void * key ,
unsigned int key_len )
2015-06-16 20:31:01 +03:00
{
2016-06-14 16:14:58 +03:00
return asn1_ber_decoder ( & rsapubkey_decoder , rsa_key , key , key_len ) ;
2015-06-16 20:31:01 +03:00
}
2015-10-08 19:26:55 +03:00
EXPORT_SYMBOL_GPL ( rsa_parse_pub_key ) ;
/**
2016-06-14 16:14:58 +03:00
* rsa_parse_priv_key ( ) - decodes the BER encoded buffer and stores in the
* provided struct rsa_key , pointers to the raw key
* as is , so that the caller can copy it or MPI parse it ,
* etc .
2015-10-08 19:26:55 +03:00
*
* @ rsa_key : struct rsa_key key representation
* @ key : key in BER format
* @ key_len : length of key
*
* Return : 0 on success or error code in case of error
*/
int rsa_parse_priv_key ( struct rsa_key * rsa_key , const void * key ,
unsigned int key_len )
{
2016-06-14 16:14:58 +03:00
return asn1_ber_decoder ( & rsaprivkey_decoder , rsa_key , key , key_len ) ;
2015-10-08 19:26:55 +03:00
}
EXPORT_SYMBOL_GPL ( rsa_parse_priv_key ) ;