]>
Commit | Line | Data |
---|---|---|
cfc2bb32 TS |
1 | /* |
2 | * RSA key extract helper | |
3 | * | |
4 | * Copyright (c) 2015, Intel Corporation | |
5 | * Authors: Tadeusz Struk <[email protected]> | |
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> | |
22287b0b TS |
18 | #include "rsapubkey-asn1.h" |
19 | #include "rsaprivkey-asn1.h" | |
cfc2bb32 TS |
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 */ | |
a9d4f82f | 32 | if (fips_enabled && (mpi_get_size(key->n) != 256 && |
cfc2bb32 TS |
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 */ | |
a9d4f82f | 66 | if (fips_enabled && (mpi_get_size(key->d) != 256 && |
cfc2bb32 TS |
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 | /** | |
22287b0b TS |
98 | * rsa_parse_pub_key() - extracts an rsa public key from BER encoded buffer |
99 | * and stores it in the provided struct rsa_key | |
cfc2bb32 TS |
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 | */ | |
22287b0b TS |
107 | int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key, |
108 | unsigned int key_len) | |
cfc2bb32 TS |
109 | { |
110 | int ret; | |
111 | ||
112 | free_mpis(rsa_key); | |
22287b0b | 113 | ret = asn1_ber_decoder(&rsapubkey_decoder, rsa_key, key, key_len); |
cfc2bb32 TS |
114 | if (ret < 0) |
115 | goto error; | |
116 | ||
117 | return 0; | |
118 | error: | |
119 | free_mpis(rsa_key); | |
120 | return ret; | |
121 | } | |
22287b0b TS |
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); |