1 /* 2 * RSA key extract helper 3 * 4 * Copyright (c) 2015, Intel Corporation 5 * Authors: Tadeusz Struk <tadeusz.struk@intel.com> 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the Free 9 * Software Foundation; either version 2 of the License, or (at your option) 10 * any later version. 11 * 12 */ 13 #include <linux/kernel.h> 14 #include <linux/export.h> 15 #include <linux/err.h> 16 #include <linux/fips.h> 17 #include <crypto/internal/rsa.h> 18 #include "rsapubkey-asn1.h" 19 #include "rsaprivkey-asn1.h" 20 21 int rsa_get_n(void *context, size_t hdrlen, unsigned char tag, 22 const void *value, size_t vlen) 23 { 24 struct rsa_key *key = context; 25 26 key->n = mpi_read_raw_data(value, vlen); 27 28 if (!key->n) 29 return -ENOMEM; 30 31 /* In FIPS mode only allow key size 2K & 3K */ 32 if (fips_enabled && (mpi_get_size(key->n) != 256 && 33 mpi_get_size(key->n) != 384)) { 34 pr_err("RSA: key size not allowed in FIPS mode\n"); 35 mpi_free(key->n); 36 key->n = NULL; 37 return -EINVAL; 38 } 39 return 0; 40 } 41 42 int rsa_get_e(void *context, size_t hdrlen, unsigned char tag, 43 const void *value, size_t vlen) 44 { 45 struct rsa_key *key = context; 46 47 key->e = mpi_read_raw_data(value, vlen); 48 49 if (!key->e) 50 return -ENOMEM; 51 52 return 0; 53 } 54 55 int rsa_get_d(void *context, size_t hdrlen, unsigned char tag, 56 const void *value, size_t vlen) 57 { 58 struct rsa_key *key = context; 59 60 key->d = mpi_read_raw_data(value, vlen); 61 62 if (!key->d) 63 return -ENOMEM; 64 65 /* In FIPS mode only allow key size 2K & 3K */ 66 if (fips_enabled && (mpi_get_size(key->d) != 256 && 67 mpi_get_size(key->d) != 384)) { 68 pr_err("RSA: key size not allowed in FIPS mode\n"); 69 mpi_free(key->d); 70 key->d = NULL; 71 return -EINVAL; 72 } 73 return 0; 74 } 75 76 static void free_mpis(struct rsa_key *key) 77 { 78 mpi_free(key->n); 79 mpi_free(key->e); 80 mpi_free(key->d); 81 key->n = NULL; 82 key->e = NULL; 83 key->d = NULL; 84 } 85 86 /** 87 * rsa_free_key() - frees rsa key allocated by rsa_parse_key() 88 * 89 * @rsa_key: struct rsa_key key representation 90 */ 91 void rsa_free_key(struct rsa_key *key) 92 { 93 free_mpis(key); 94 } 95 EXPORT_SYMBOL_GPL(rsa_free_key); 96 97 /** 98 * rsa_parse_pub_key() - extracts an rsa public key from BER encoded buffer 99 * and stores it in the provided struct rsa_key 100 * 101 * @rsa_key: struct rsa_key key representation 102 * @key: key in BER format 103 * @key_len: length of key 104 * 105 * Return: 0 on success or error code in case of error 106 */ 107 int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key, 108 unsigned int key_len) 109 { 110 int ret; 111 112 free_mpis(rsa_key); 113 ret = asn1_ber_decoder(&rsapubkey_decoder, rsa_key, key, key_len); 114 if (ret < 0) 115 goto error; 116 117 return 0; 118 error: 119 free_mpis(rsa_key); 120 return ret; 121 } 122 EXPORT_SYMBOL_GPL(rsa_parse_pub_key); 123 124 /** 125 * rsa_parse_pub_key() - extracts an rsa private key from BER encoded buffer 126 * and stores it in the provided struct rsa_key 127 * 128 * @rsa_key: struct rsa_key key representation 129 * @key: key in BER format 130 * @key_len: length of key 131 * 132 * Return: 0 on success or error code in case of error 133 */ 134 int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key, 135 unsigned int key_len) 136 { 137 int ret; 138 139 free_mpis(rsa_key); 140 ret = asn1_ber_decoder(&rsaprivkey_decoder, rsa_key, key, key_len); 141 if (ret < 0) 142 goto error; 143 144 return 0; 145 error: 146 free_mpis(rsa_key); 147 return ret; 148 } 149 EXPORT_SYMBOL_GPL(rsa_parse_priv_key); 150