diff options
Diffstat (limited to 'lib/digsig.c')
-rw-r--r-- | lib/digsig.c | 52 |
1 files changed, 23 insertions, 29 deletions
diff --git a/lib/digsig.c b/lib/digsig.c index fd2402f67f89..286d558033e2 100644 --- a/lib/digsig.c +++ b/lib/digsig.c | |||
@@ -34,14 +34,9 @@ static int pkcs_1_v1_5_decode_emsa(const unsigned char *msg, | |||
34 | unsigned long msglen, | 34 | unsigned long msglen, |
35 | unsigned long modulus_bitlen, | 35 | unsigned long modulus_bitlen, |
36 | unsigned char *out, | 36 | unsigned char *out, |
37 | unsigned long *outlen, | 37 | unsigned long *outlen) |
38 | int *is_valid) | ||
39 | { | 38 | { |
40 | unsigned long modulus_len, ps_len, i; | 39 | unsigned long modulus_len, ps_len, i; |
41 | int result; | ||
42 | |||
43 | /* default to invalid packet */ | ||
44 | *is_valid = 0; | ||
45 | 40 | ||
46 | modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); | 41 | modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); |
47 | 42 | ||
@@ -50,39 +45,30 @@ static int pkcs_1_v1_5_decode_emsa(const unsigned char *msg, | |||
50 | return -EINVAL; | 45 | return -EINVAL; |
51 | 46 | ||
52 | /* separate encoded message */ | 47 | /* separate encoded message */ |
53 | if ((msg[0] != 0x00) || (msg[1] != (unsigned char)1)) { | 48 | if ((msg[0] != 0x00) || (msg[1] != (unsigned char)1)) |
54 | result = -EINVAL; | 49 | return -EINVAL; |
55 | goto bail; | ||
56 | } | ||
57 | 50 | ||
58 | for (i = 2; i < modulus_len - 1; i++) | 51 | for (i = 2; i < modulus_len - 1; i++) |
59 | if (msg[i] != 0xFF) | 52 | if (msg[i] != 0xFF) |
60 | break; | 53 | break; |
61 | 54 | ||
62 | /* separator check */ | 55 | /* separator check */ |
63 | if (msg[i] != 0) { | 56 | if (msg[i] != 0) |
64 | /* There was no octet with hexadecimal value 0x00 | 57 | /* There was no octet with hexadecimal value 0x00 |
65 | to separate ps from m. */ | 58 | to separate ps from m. */ |
66 | result = -EINVAL; | 59 | return -EINVAL; |
67 | goto bail; | ||
68 | } | ||
69 | 60 | ||
70 | ps_len = i - 2; | 61 | ps_len = i - 2; |
71 | 62 | ||
72 | if (*outlen < (msglen - (2 + ps_len + 1))) { | 63 | if (*outlen < (msglen - (2 + ps_len + 1))) { |
73 | *outlen = msglen - (2 + ps_len + 1); | 64 | *outlen = msglen - (2 + ps_len + 1); |
74 | result = -EOVERFLOW; | 65 | return -EOVERFLOW; |
75 | goto bail; | ||
76 | } | 66 | } |
77 | 67 | ||
78 | *outlen = (msglen - (2 + ps_len + 1)); | 68 | *outlen = (msglen - (2 + ps_len + 1)); |
79 | memcpy(out, &msg[2 + ps_len + 1], *outlen); | 69 | memcpy(out, &msg[2 + ps_len + 1], *outlen); |
80 | 70 | ||
81 | /* valid packet */ | 71 | return 0; |
82 | *is_valid = 1; | ||
83 | result = 0; | ||
84 | bail: | ||
85 | return result; | ||
86 | } | 72 | } |
87 | 73 | ||
88 | /* | 74 | /* |
@@ -96,7 +82,7 @@ static int digsig_verify_rsa(struct key *key, | |||
96 | unsigned long len; | 82 | unsigned long len; |
97 | unsigned long mlen, mblen; | 83 | unsigned long mlen, mblen; |
98 | unsigned nret, l; | 84 | unsigned nret, l; |
99 | int valid, head, i; | 85 | int head, i; |
100 | unsigned char *out1 = NULL, *out2 = NULL; | 86 | unsigned char *out1 = NULL, *out2 = NULL; |
101 | MPI in = NULL, res = NULL, pkey[2]; | 87 | MPI in = NULL, res = NULL, pkey[2]; |
102 | uint8_t *p, *datap, *endp; | 88 | uint8_t *p, *datap, *endp; |
@@ -105,6 +91,10 @@ static int digsig_verify_rsa(struct key *key, | |||
105 | 91 | ||
106 | down_read(&key->sem); | 92 | down_read(&key->sem); |
107 | ukp = key->payload.data; | 93 | ukp = key->payload.data; |
94 | |||
95 | if (ukp->datalen < sizeof(*pkh)) | ||
96 | goto err1; | ||
97 | |||
108 | pkh = (struct pubkey_hdr *)ukp->data; | 98 | pkh = (struct pubkey_hdr *)ukp->data; |
109 | 99 | ||
110 | if (pkh->version != 1) | 100 | if (pkh->version != 1) |
@@ -117,18 +107,23 @@ static int digsig_verify_rsa(struct key *key, | |||
117 | goto err1; | 107 | goto err1; |
118 | 108 | ||
119 | datap = pkh->mpi; | 109 | datap = pkh->mpi; |
120 | endp = datap + ukp->datalen; | 110 | endp = ukp->data + ukp->datalen; |
111 | |||
112 | err = -ENOMEM; | ||
121 | 113 | ||
122 | for (i = 0; i < pkh->nmpi; i++) { | 114 | for (i = 0; i < pkh->nmpi; i++) { |
123 | unsigned int remaining = endp - datap; | 115 | unsigned int remaining = endp - datap; |
124 | pkey[i] = mpi_read_from_buffer(datap, &remaining); | 116 | pkey[i] = mpi_read_from_buffer(datap, &remaining); |
117 | if (!pkey[i]) | ||
118 | goto err; | ||
125 | datap += remaining; | 119 | datap += remaining; |
126 | } | 120 | } |
127 | 121 | ||
128 | mblen = mpi_get_nbits(pkey[0]); | 122 | mblen = mpi_get_nbits(pkey[0]); |
129 | mlen = (mblen + 7)/8; | 123 | mlen = (mblen + 7)/8; |
130 | 124 | ||
131 | err = -ENOMEM; | 125 | if (mlen == 0) |
126 | goto err; | ||
132 | 127 | ||
133 | out1 = kzalloc(mlen, GFP_KERNEL); | 128 | out1 = kzalloc(mlen, GFP_KERNEL); |
134 | if (!out1) | 129 | if (!out1) |
@@ -167,10 +162,9 @@ static int digsig_verify_rsa(struct key *key, | |||
167 | memset(out1, 0, head); | 162 | memset(out1, 0, head); |
168 | memcpy(out1 + head, p, l); | 163 | memcpy(out1 + head, p, l); |
169 | 164 | ||
170 | err = -EINVAL; | 165 | err = pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len); |
171 | pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len, &valid); | ||
172 | 166 | ||
173 | if (valid && len == hlen) | 167 | if (!err && len == hlen) |
174 | err = memcmp(out2, h, hlen); | 168 | err = memcmp(out2, h, hlen); |
175 | 169 | ||
176 | err: | 170 | err: |
@@ -178,8 +172,8 @@ err: | |||
178 | mpi_free(res); | 172 | mpi_free(res); |
179 | kfree(out1); | 173 | kfree(out1); |
180 | kfree(out2); | 174 | kfree(out2); |
181 | mpi_free(pkey[0]); | 175 | while (--i >= 0) |
182 | mpi_free(pkey[1]); | 176 | mpi_free(pkey[i]); |
183 | err1: | 177 | err1: |
184 | up_read(&key->sem); | 178 | up_read(&key->sem); |
185 | 179 | ||