1*2a598d0bSHerbert Xu /* mpicoder.c - Coder for the external representation of MPIs
2*2a598d0bSHerbert Xu * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
3*2a598d0bSHerbert Xu *
4*2a598d0bSHerbert Xu * This file is part of GnuPG.
5*2a598d0bSHerbert Xu *
6*2a598d0bSHerbert Xu * GnuPG is free software; you can redistribute it and/or modify
7*2a598d0bSHerbert Xu * it under the terms of the GNU General Public License as published by
8*2a598d0bSHerbert Xu * the Free Software Foundation; either version 2 of the License, or
9*2a598d0bSHerbert Xu * (at your option) any later version.
10*2a598d0bSHerbert Xu *
11*2a598d0bSHerbert Xu * GnuPG is distributed in the hope that it will be useful,
12*2a598d0bSHerbert Xu * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*2a598d0bSHerbert Xu * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*2a598d0bSHerbert Xu * GNU General Public License for more details.
15*2a598d0bSHerbert Xu *
16*2a598d0bSHerbert Xu * You should have received a copy of the GNU General Public License
17*2a598d0bSHerbert Xu * along with this program; if not, write to the Free Software
18*2a598d0bSHerbert Xu * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19*2a598d0bSHerbert Xu */
20*2a598d0bSHerbert Xu
21*2a598d0bSHerbert Xu #include <linux/bitops.h>
22*2a598d0bSHerbert Xu #include <linux/count_zeros.h>
23*2a598d0bSHerbert Xu #include <linux/byteorder/generic.h>
24*2a598d0bSHerbert Xu #include <linux/scatterlist.h>
25*2a598d0bSHerbert Xu #include <linux/string.h>
26*2a598d0bSHerbert Xu #include "mpi-internal.h"
27*2a598d0bSHerbert Xu
28*2a598d0bSHerbert Xu #define MAX_EXTERN_SCAN_BYTES (16*1024*1024)
29*2a598d0bSHerbert Xu #define MAX_EXTERN_MPI_BITS 16384
30*2a598d0bSHerbert Xu
31*2a598d0bSHerbert Xu /**
32*2a598d0bSHerbert Xu * mpi_read_raw_data - Read a raw byte stream as a positive integer
33*2a598d0bSHerbert Xu * @xbuffer: The data to read
34*2a598d0bSHerbert Xu * @nbytes: The amount of data to read
35*2a598d0bSHerbert Xu */
mpi_read_raw_data(const void * xbuffer,size_t nbytes)36*2a598d0bSHerbert Xu MPI mpi_read_raw_data(const void *xbuffer, size_t nbytes)
37*2a598d0bSHerbert Xu {
38*2a598d0bSHerbert Xu const uint8_t *buffer = xbuffer;
39*2a598d0bSHerbert Xu int i, j;
40*2a598d0bSHerbert Xu unsigned nbits, nlimbs;
41*2a598d0bSHerbert Xu mpi_limb_t a;
42*2a598d0bSHerbert Xu MPI val = NULL;
43*2a598d0bSHerbert Xu
44*2a598d0bSHerbert Xu while (nbytes > 0 && buffer[0] == 0) {
45*2a598d0bSHerbert Xu buffer++;
46*2a598d0bSHerbert Xu nbytes--;
47*2a598d0bSHerbert Xu }
48*2a598d0bSHerbert Xu
49*2a598d0bSHerbert Xu nbits = nbytes * 8;
50*2a598d0bSHerbert Xu if (nbits > MAX_EXTERN_MPI_BITS) {
51*2a598d0bSHerbert Xu pr_info("MPI: mpi too large (%u bits)\n", nbits);
52*2a598d0bSHerbert Xu return NULL;
53*2a598d0bSHerbert Xu }
54*2a598d0bSHerbert Xu if (nbytes > 0)
55*2a598d0bSHerbert Xu nbits -= count_leading_zeros(buffer[0]) - (BITS_PER_LONG - 8);
56*2a598d0bSHerbert Xu
57*2a598d0bSHerbert Xu nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB);
58*2a598d0bSHerbert Xu val = mpi_alloc(nlimbs);
59*2a598d0bSHerbert Xu if (!val)
60*2a598d0bSHerbert Xu return NULL;
61*2a598d0bSHerbert Xu val->nbits = nbits;
62*2a598d0bSHerbert Xu val->sign = 0;
63*2a598d0bSHerbert Xu val->nlimbs = nlimbs;
64*2a598d0bSHerbert Xu
65*2a598d0bSHerbert Xu if (nbytes > 0) {
66*2a598d0bSHerbert Xu i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
67*2a598d0bSHerbert Xu i %= BYTES_PER_MPI_LIMB;
68*2a598d0bSHerbert Xu for (j = nlimbs; j > 0; j--) {
69*2a598d0bSHerbert Xu a = 0;
70*2a598d0bSHerbert Xu for (; i < BYTES_PER_MPI_LIMB; i++) {
71*2a598d0bSHerbert Xu a <<= 8;
72*2a598d0bSHerbert Xu a |= *buffer++;
73*2a598d0bSHerbert Xu }
74*2a598d0bSHerbert Xu i = 0;
75*2a598d0bSHerbert Xu val->d[j - 1] = a;
76*2a598d0bSHerbert Xu }
77*2a598d0bSHerbert Xu }
78*2a598d0bSHerbert Xu return val;
79*2a598d0bSHerbert Xu }
80*2a598d0bSHerbert Xu EXPORT_SYMBOL_GPL(mpi_read_raw_data);
81*2a598d0bSHerbert Xu
mpi_read_from_buffer(const void * xbuffer,unsigned * ret_nread)82*2a598d0bSHerbert Xu MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread)
83*2a598d0bSHerbert Xu {
84*2a598d0bSHerbert Xu const uint8_t *buffer = xbuffer;
85*2a598d0bSHerbert Xu unsigned int nbits, nbytes;
86*2a598d0bSHerbert Xu MPI val;
87*2a598d0bSHerbert Xu
88*2a598d0bSHerbert Xu if (*ret_nread < 2)
89*2a598d0bSHerbert Xu return ERR_PTR(-EINVAL);
90*2a598d0bSHerbert Xu nbits = buffer[0] << 8 | buffer[1];
91*2a598d0bSHerbert Xu
92*2a598d0bSHerbert Xu if (nbits > MAX_EXTERN_MPI_BITS) {
93*2a598d0bSHerbert Xu pr_info("MPI: mpi too large (%u bits)\n", nbits);
94*2a598d0bSHerbert Xu return ERR_PTR(-EINVAL);
95*2a598d0bSHerbert Xu }
96*2a598d0bSHerbert Xu
97*2a598d0bSHerbert Xu nbytes = DIV_ROUND_UP(nbits, 8);
98*2a598d0bSHerbert Xu if (nbytes + 2 > *ret_nread) {
99*2a598d0bSHerbert Xu pr_info("MPI: mpi larger than buffer nbytes=%u ret_nread=%u\n",
100*2a598d0bSHerbert Xu nbytes, *ret_nread);
101*2a598d0bSHerbert Xu return ERR_PTR(-EINVAL);
102*2a598d0bSHerbert Xu }
103*2a598d0bSHerbert Xu
104*2a598d0bSHerbert Xu val = mpi_read_raw_data(buffer + 2, nbytes);
105*2a598d0bSHerbert Xu if (!val)
106*2a598d0bSHerbert Xu return ERR_PTR(-ENOMEM);
107*2a598d0bSHerbert Xu
108*2a598d0bSHerbert Xu *ret_nread = nbytes + 2;
109*2a598d0bSHerbert Xu return val;
110*2a598d0bSHerbert Xu }
111*2a598d0bSHerbert Xu EXPORT_SYMBOL_GPL(mpi_read_from_buffer);
112*2a598d0bSHerbert Xu
113*2a598d0bSHerbert Xu /****************
114*2a598d0bSHerbert Xu * Fill the mpi VAL from the hex string in STR.
115*2a598d0bSHerbert Xu */
mpi_fromstr(MPI val,const char * str)116*2a598d0bSHerbert Xu int mpi_fromstr(MPI val, const char *str)
117*2a598d0bSHerbert Xu {
118*2a598d0bSHerbert Xu int sign = 0;
119*2a598d0bSHerbert Xu int prepend_zero = 0;
120*2a598d0bSHerbert Xu int i, j, c, c1, c2;
121*2a598d0bSHerbert Xu unsigned int nbits, nbytes, nlimbs;
122*2a598d0bSHerbert Xu mpi_limb_t a;
123*2a598d0bSHerbert Xu
124*2a598d0bSHerbert Xu if (*str == '-') {
125*2a598d0bSHerbert Xu sign = 1;
126*2a598d0bSHerbert Xu str++;
127*2a598d0bSHerbert Xu }
128*2a598d0bSHerbert Xu
129*2a598d0bSHerbert Xu /* Skip optional hex prefix. */
130*2a598d0bSHerbert Xu if (*str == '0' && str[1] == 'x')
131*2a598d0bSHerbert Xu str += 2;
132*2a598d0bSHerbert Xu
133*2a598d0bSHerbert Xu nbits = strlen(str);
134*2a598d0bSHerbert Xu if (nbits > MAX_EXTERN_SCAN_BYTES) {
135*2a598d0bSHerbert Xu mpi_clear(val);
136*2a598d0bSHerbert Xu return -EINVAL;
137*2a598d0bSHerbert Xu }
138*2a598d0bSHerbert Xu nbits *= 4;
139*2a598d0bSHerbert Xu if ((nbits % 8))
140*2a598d0bSHerbert Xu prepend_zero = 1;
141*2a598d0bSHerbert Xu
142*2a598d0bSHerbert Xu nbytes = (nbits+7) / 8;
143*2a598d0bSHerbert Xu nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
144*2a598d0bSHerbert Xu
145*2a598d0bSHerbert Xu if (val->alloced < nlimbs)
146*2a598d0bSHerbert Xu mpi_resize(val, nlimbs);
147*2a598d0bSHerbert Xu
148*2a598d0bSHerbert Xu i = BYTES_PER_MPI_LIMB - (nbytes % BYTES_PER_MPI_LIMB);
149*2a598d0bSHerbert Xu i %= BYTES_PER_MPI_LIMB;
150*2a598d0bSHerbert Xu j = val->nlimbs = nlimbs;
151*2a598d0bSHerbert Xu val->sign = sign;
152*2a598d0bSHerbert Xu for (; j > 0; j--) {
153*2a598d0bSHerbert Xu a = 0;
154*2a598d0bSHerbert Xu for (; i < BYTES_PER_MPI_LIMB; i++) {
155*2a598d0bSHerbert Xu if (prepend_zero) {
156*2a598d0bSHerbert Xu c1 = '0';
157*2a598d0bSHerbert Xu prepend_zero = 0;
158*2a598d0bSHerbert Xu } else
159*2a598d0bSHerbert Xu c1 = *str++;
160*2a598d0bSHerbert Xu
161*2a598d0bSHerbert Xu if (!c1) {
162*2a598d0bSHerbert Xu mpi_clear(val);
163*2a598d0bSHerbert Xu return -EINVAL;
164*2a598d0bSHerbert Xu }
165*2a598d0bSHerbert Xu c2 = *str++;
166*2a598d0bSHerbert Xu if (!c2) {
167*2a598d0bSHerbert Xu mpi_clear(val);
168*2a598d0bSHerbert Xu return -EINVAL;
169*2a598d0bSHerbert Xu }
170*2a598d0bSHerbert Xu if (c1 >= '0' && c1 <= '9')
171*2a598d0bSHerbert Xu c = c1 - '0';
172*2a598d0bSHerbert Xu else if (c1 >= 'a' && c1 <= 'f')
173*2a598d0bSHerbert Xu c = c1 - 'a' + 10;
174*2a598d0bSHerbert Xu else if (c1 >= 'A' && c1 <= 'F')
175*2a598d0bSHerbert Xu c = c1 - 'A' + 10;
176*2a598d0bSHerbert Xu else {
177*2a598d0bSHerbert Xu mpi_clear(val);
178*2a598d0bSHerbert Xu return -EINVAL;
179*2a598d0bSHerbert Xu }
180*2a598d0bSHerbert Xu c <<= 4;
181*2a598d0bSHerbert Xu if (c2 >= '0' && c2 <= '9')
182*2a598d0bSHerbert Xu c |= c2 - '0';
183*2a598d0bSHerbert Xu else if (c2 >= 'a' && c2 <= 'f')
184*2a598d0bSHerbert Xu c |= c2 - 'a' + 10;
185*2a598d0bSHerbert Xu else if (c2 >= 'A' && c2 <= 'F')
186*2a598d0bSHerbert Xu c |= c2 - 'A' + 10;
187*2a598d0bSHerbert Xu else {
188*2a598d0bSHerbert Xu mpi_clear(val);
189*2a598d0bSHerbert Xu return -EINVAL;
190*2a598d0bSHerbert Xu }
191*2a598d0bSHerbert Xu a <<= 8;
192*2a598d0bSHerbert Xu a |= c;
193*2a598d0bSHerbert Xu }
194*2a598d0bSHerbert Xu i = 0;
195*2a598d0bSHerbert Xu val->d[j-1] = a;
196*2a598d0bSHerbert Xu }
197*2a598d0bSHerbert Xu
198*2a598d0bSHerbert Xu return 0;
199*2a598d0bSHerbert Xu }
200*2a598d0bSHerbert Xu EXPORT_SYMBOL_GPL(mpi_fromstr);
201*2a598d0bSHerbert Xu
mpi_scanval(const char * string)202*2a598d0bSHerbert Xu MPI mpi_scanval(const char *string)
203*2a598d0bSHerbert Xu {
204*2a598d0bSHerbert Xu MPI a;
205*2a598d0bSHerbert Xu
206*2a598d0bSHerbert Xu a = mpi_alloc(0);
207*2a598d0bSHerbert Xu if (!a)
208*2a598d0bSHerbert Xu return NULL;
209*2a598d0bSHerbert Xu
210*2a598d0bSHerbert Xu if (mpi_fromstr(a, string)) {
211*2a598d0bSHerbert Xu mpi_free(a);
212*2a598d0bSHerbert Xu return NULL;
213*2a598d0bSHerbert Xu }
214*2a598d0bSHerbert Xu mpi_normalize(a);
215*2a598d0bSHerbert Xu return a;
216*2a598d0bSHerbert Xu }
217*2a598d0bSHerbert Xu EXPORT_SYMBOL_GPL(mpi_scanval);
218*2a598d0bSHerbert Xu
count_lzeros(MPI a)219*2a598d0bSHerbert Xu static int count_lzeros(MPI a)
220*2a598d0bSHerbert Xu {
221*2a598d0bSHerbert Xu mpi_limb_t alimb;
222*2a598d0bSHerbert Xu int i, lzeros = 0;
223*2a598d0bSHerbert Xu
224*2a598d0bSHerbert Xu for (i = a->nlimbs - 1; i >= 0; i--) {
225*2a598d0bSHerbert Xu alimb = a->d[i];
226*2a598d0bSHerbert Xu if (alimb == 0) {
227*2a598d0bSHerbert Xu lzeros += sizeof(mpi_limb_t);
228*2a598d0bSHerbert Xu } else {
229*2a598d0bSHerbert Xu lzeros += count_leading_zeros(alimb) / 8;
230*2a598d0bSHerbert Xu break;
231*2a598d0bSHerbert Xu }
232*2a598d0bSHerbert Xu }
233*2a598d0bSHerbert Xu return lzeros;
234*2a598d0bSHerbert Xu }
235*2a598d0bSHerbert Xu
236*2a598d0bSHerbert Xu /**
237*2a598d0bSHerbert Xu * mpi_read_buffer() - read MPI to a buffer provided by user (msb first)
238*2a598d0bSHerbert Xu *
239*2a598d0bSHerbert Xu * @a: a multi precision integer
240*2a598d0bSHerbert Xu * @buf: buffer to which the output will be written to. Needs to be at
241*2a598d0bSHerbert Xu * least mpi_get_size(a) long.
242*2a598d0bSHerbert Xu * @buf_len: size of the buf.
243*2a598d0bSHerbert Xu * @nbytes: receives the actual length of the data written on success and
244*2a598d0bSHerbert Xu * the data to-be-written on -EOVERFLOW in case buf_len was too
245*2a598d0bSHerbert Xu * small.
246*2a598d0bSHerbert Xu * @sign: if not NULL, it will be set to the sign of a.
247*2a598d0bSHerbert Xu *
248*2a598d0bSHerbert Xu * Return: 0 on success or error code in case of error
249*2a598d0bSHerbert Xu */
mpi_read_buffer(MPI a,uint8_t * buf,unsigned buf_len,unsigned * nbytes,int * sign)250*2a598d0bSHerbert Xu int mpi_read_buffer(MPI a, uint8_t *buf, unsigned buf_len, unsigned *nbytes,
251*2a598d0bSHerbert Xu int *sign)
252*2a598d0bSHerbert Xu {
253*2a598d0bSHerbert Xu uint8_t *p;
254*2a598d0bSHerbert Xu #if BYTES_PER_MPI_LIMB == 4
255*2a598d0bSHerbert Xu __be32 alimb;
256*2a598d0bSHerbert Xu #elif BYTES_PER_MPI_LIMB == 8
257*2a598d0bSHerbert Xu __be64 alimb;
258*2a598d0bSHerbert Xu #else
259*2a598d0bSHerbert Xu #error please implement for this limb size.
260*2a598d0bSHerbert Xu #endif
261*2a598d0bSHerbert Xu unsigned int n = mpi_get_size(a);
262*2a598d0bSHerbert Xu int i, lzeros;
263*2a598d0bSHerbert Xu
264*2a598d0bSHerbert Xu if (!buf || !nbytes)
265*2a598d0bSHerbert Xu return -EINVAL;
266*2a598d0bSHerbert Xu
267*2a598d0bSHerbert Xu if (sign)
268*2a598d0bSHerbert Xu *sign = a->sign;
269*2a598d0bSHerbert Xu
270*2a598d0bSHerbert Xu lzeros = count_lzeros(a);
271*2a598d0bSHerbert Xu
272*2a598d0bSHerbert Xu if (buf_len < n - lzeros) {
273*2a598d0bSHerbert Xu *nbytes = n - lzeros;
274*2a598d0bSHerbert Xu return -EOVERFLOW;
275*2a598d0bSHerbert Xu }
276*2a598d0bSHerbert Xu
277*2a598d0bSHerbert Xu p = buf;
278*2a598d0bSHerbert Xu *nbytes = n - lzeros;
279*2a598d0bSHerbert Xu
280*2a598d0bSHerbert Xu for (i = a->nlimbs - 1 - lzeros / BYTES_PER_MPI_LIMB,
281*2a598d0bSHerbert Xu lzeros %= BYTES_PER_MPI_LIMB;
282*2a598d0bSHerbert Xu i >= 0; i--) {
283*2a598d0bSHerbert Xu #if BYTES_PER_MPI_LIMB == 4
284*2a598d0bSHerbert Xu alimb = cpu_to_be32(a->d[i]);
285*2a598d0bSHerbert Xu #elif BYTES_PER_MPI_LIMB == 8
286*2a598d0bSHerbert Xu alimb = cpu_to_be64(a->d[i]);
287*2a598d0bSHerbert Xu #else
288*2a598d0bSHerbert Xu #error please implement for this limb size.
289*2a598d0bSHerbert Xu #endif
290*2a598d0bSHerbert Xu memcpy(p, (u8 *)&alimb + lzeros, BYTES_PER_MPI_LIMB - lzeros);
291*2a598d0bSHerbert Xu p += BYTES_PER_MPI_LIMB - lzeros;
292*2a598d0bSHerbert Xu lzeros = 0;
293*2a598d0bSHerbert Xu }
294*2a598d0bSHerbert Xu return 0;
295*2a598d0bSHerbert Xu }
296*2a598d0bSHerbert Xu EXPORT_SYMBOL_GPL(mpi_read_buffer);
297*2a598d0bSHerbert Xu
298*2a598d0bSHerbert Xu /*
299*2a598d0bSHerbert Xu * mpi_get_buffer() - Returns an allocated buffer with the MPI (msb first).
300*2a598d0bSHerbert Xu * Caller must free the return string.
301*2a598d0bSHerbert Xu * This function does return a 0 byte buffer with nbytes set to zero if the
302*2a598d0bSHerbert Xu * value of A is zero.
303*2a598d0bSHerbert Xu *
304*2a598d0bSHerbert Xu * @a: a multi precision integer.
305*2a598d0bSHerbert Xu * @nbytes: receives the length of this buffer.
306*2a598d0bSHerbert Xu * @sign: if not NULL, it will be set to the sign of the a.
307*2a598d0bSHerbert Xu *
308*2a598d0bSHerbert Xu * Return: Pointer to MPI buffer or NULL on error
309*2a598d0bSHerbert Xu */
mpi_get_buffer(MPI a,unsigned * nbytes,int * sign)310*2a598d0bSHerbert Xu void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign)
311*2a598d0bSHerbert Xu {
312*2a598d0bSHerbert Xu uint8_t *buf;
313*2a598d0bSHerbert Xu unsigned int n;
314*2a598d0bSHerbert Xu int ret;
315*2a598d0bSHerbert Xu
316*2a598d0bSHerbert Xu if (!nbytes)
317*2a598d0bSHerbert Xu return NULL;
318*2a598d0bSHerbert Xu
319*2a598d0bSHerbert Xu n = mpi_get_size(a);
320*2a598d0bSHerbert Xu
321*2a598d0bSHerbert Xu if (!n)
322*2a598d0bSHerbert Xu n++;
323*2a598d0bSHerbert Xu
324*2a598d0bSHerbert Xu buf = kmalloc(n, GFP_KERNEL);
325*2a598d0bSHerbert Xu
326*2a598d0bSHerbert Xu if (!buf)
327*2a598d0bSHerbert Xu return NULL;
328*2a598d0bSHerbert Xu
329*2a598d0bSHerbert Xu ret = mpi_read_buffer(a, buf, n, nbytes, sign);
330*2a598d0bSHerbert Xu
331*2a598d0bSHerbert Xu if (ret) {
332*2a598d0bSHerbert Xu kfree(buf);
333*2a598d0bSHerbert Xu return NULL;
334*2a598d0bSHerbert Xu }
335*2a598d0bSHerbert Xu return buf;
336*2a598d0bSHerbert Xu }
337*2a598d0bSHerbert Xu EXPORT_SYMBOL_GPL(mpi_get_buffer);
338*2a598d0bSHerbert Xu
339*2a598d0bSHerbert Xu /**
340*2a598d0bSHerbert Xu * mpi_write_to_sgl() - Funnction exports MPI to an sgl (msb first)
341*2a598d0bSHerbert Xu *
342*2a598d0bSHerbert Xu * This function works in the same way as the mpi_read_buffer, but it
343*2a598d0bSHerbert Xu * takes an sgl instead of u8 * buf.
344*2a598d0bSHerbert Xu *
345*2a598d0bSHerbert Xu * @a: a multi precision integer
346*2a598d0bSHerbert Xu * @sgl: scatterlist to write to. Needs to be at least
347*2a598d0bSHerbert Xu * mpi_get_size(a) long.
348*2a598d0bSHerbert Xu * @nbytes: the number of bytes to write. Leading bytes will be
349*2a598d0bSHerbert Xu * filled with zero.
350*2a598d0bSHerbert Xu * @sign: if not NULL, it will be set to the sign of a.
351*2a598d0bSHerbert Xu *
352*2a598d0bSHerbert Xu * Return: 0 on success or error code in case of error
353*2a598d0bSHerbert Xu */
mpi_write_to_sgl(MPI a,struct scatterlist * sgl,unsigned nbytes,int * sign)354*2a598d0bSHerbert Xu int mpi_write_to_sgl(MPI a, struct scatterlist *sgl, unsigned nbytes,
355*2a598d0bSHerbert Xu int *sign)
356*2a598d0bSHerbert Xu {
357*2a598d0bSHerbert Xu u8 *p, *p2;
358*2a598d0bSHerbert Xu #if BYTES_PER_MPI_LIMB == 4
359*2a598d0bSHerbert Xu __be32 alimb;
360*2a598d0bSHerbert Xu #elif BYTES_PER_MPI_LIMB == 8
361*2a598d0bSHerbert Xu __be64 alimb;
362*2a598d0bSHerbert Xu #else
363*2a598d0bSHerbert Xu #error please implement for this limb size.
364*2a598d0bSHerbert Xu #endif
365*2a598d0bSHerbert Xu unsigned int n = mpi_get_size(a);
366*2a598d0bSHerbert Xu struct sg_mapping_iter miter;
367*2a598d0bSHerbert Xu int i, x, buf_len;
368*2a598d0bSHerbert Xu int nents;
369*2a598d0bSHerbert Xu
370*2a598d0bSHerbert Xu if (sign)
371*2a598d0bSHerbert Xu *sign = a->sign;
372*2a598d0bSHerbert Xu
373*2a598d0bSHerbert Xu if (nbytes < n)
374*2a598d0bSHerbert Xu return -EOVERFLOW;
375*2a598d0bSHerbert Xu
376*2a598d0bSHerbert Xu nents = sg_nents_for_len(sgl, nbytes);
377*2a598d0bSHerbert Xu if (nents < 0)
378*2a598d0bSHerbert Xu return -EINVAL;
379*2a598d0bSHerbert Xu
380*2a598d0bSHerbert Xu sg_miter_start(&miter, sgl, nents, SG_MITER_ATOMIC | SG_MITER_TO_SG);
381*2a598d0bSHerbert Xu sg_miter_next(&miter);
382*2a598d0bSHerbert Xu buf_len = miter.length;
383*2a598d0bSHerbert Xu p2 = miter.addr;
384*2a598d0bSHerbert Xu
385*2a598d0bSHerbert Xu while (nbytes > n) {
386*2a598d0bSHerbert Xu i = min_t(unsigned, nbytes - n, buf_len);
387*2a598d0bSHerbert Xu memset(p2, 0, i);
388*2a598d0bSHerbert Xu p2 += i;
389*2a598d0bSHerbert Xu nbytes -= i;
390*2a598d0bSHerbert Xu
391*2a598d0bSHerbert Xu buf_len -= i;
392*2a598d0bSHerbert Xu if (!buf_len) {
393*2a598d0bSHerbert Xu sg_miter_next(&miter);
394*2a598d0bSHerbert Xu buf_len = miter.length;
395*2a598d0bSHerbert Xu p2 = miter.addr;
396*2a598d0bSHerbert Xu }
397*2a598d0bSHerbert Xu }
398*2a598d0bSHerbert Xu
399*2a598d0bSHerbert Xu for (i = a->nlimbs - 1; i >= 0; i--) {
400*2a598d0bSHerbert Xu #if BYTES_PER_MPI_LIMB == 4
401*2a598d0bSHerbert Xu alimb = a->d[i] ? cpu_to_be32(a->d[i]) : 0;
402*2a598d0bSHerbert Xu #elif BYTES_PER_MPI_LIMB == 8
403*2a598d0bSHerbert Xu alimb = a->d[i] ? cpu_to_be64(a->d[i]) : 0;
404*2a598d0bSHerbert Xu #else
405*2a598d0bSHerbert Xu #error please implement for this limb size.
406*2a598d0bSHerbert Xu #endif
407*2a598d0bSHerbert Xu p = (u8 *)&alimb;
408*2a598d0bSHerbert Xu
409*2a598d0bSHerbert Xu for (x = 0; x < sizeof(alimb); x++) {
410*2a598d0bSHerbert Xu *p2++ = *p++;
411*2a598d0bSHerbert Xu if (!--buf_len) {
412*2a598d0bSHerbert Xu sg_miter_next(&miter);
413*2a598d0bSHerbert Xu buf_len = miter.length;
414*2a598d0bSHerbert Xu p2 = miter.addr;
415*2a598d0bSHerbert Xu }
416*2a598d0bSHerbert Xu }
417*2a598d0bSHerbert Xu }
418*2a598d0bSHerbert Xu
419*2a598d0bSHerbert Xu sg_miter_stop(&miter);
420*2a598d0bSHerbert Xu return 0;
421*2a598d0bSHerbert Xu }
422*2a598d0bSHerbert Xu EXPORT_SYMBOL_GPL(mpi_write_to_sgl);
423*2a598d0bSHerbert Xu
424*2a598d0bSHerbert Xu /*
425*2a598d0bSHerbert Xu * mpi_read_raw_from_sgl() - Function allocates an MPI and populates it with
426*2a598d0bSHerbert Xu * data from the sgl
427*2a598d0bSHerbert Xu *
428*2a598d0bSHerbert Xu * This function works in the same way as the mpi_read_raw_data, but it
429*2a598d0bSHerbert Xu * takes an sgl instead of void * buffer. i.e. it allocates
430*2a598d0bSHerbert Xu * a new MPI and reads the content of the sgl to the MPI.
431*2a598d0bSHerbert Xu *
432*2a598d0bSHerbert Xu * @sgl: scatterlist to read from
433*2a598d0bSHerbert Xu * @nbytes: number of bytes to read
434*2a598d0bSHerbert Xu *
435*2a598d0bSHerbert Xu * Return: Pointer to a new MPI or NULL on error
436*2a598d0bSHerbert Xu */
mpi_read_raw_from_sgl(struct scatterlist * sgl,unsigned int nbytes)437*2a598d0bSHerbert Xu MPI mpi_read_raw_from_sgl(struct scatterlist *sgl, unsigned int nbytes)
438*2a598d0bSHerbert Xu {
439*2a598d0bSHerbert Xu struct sg_mapping_iter miter;
440*2a598d0bSHerbert Xu unsigned int nbits, nlimbs;
441*2a598d0bSHerbert Xu int x, j, z, lzeros, ents;
442*2a598d0bSHerbert Xu unsigned int len;
443*2a598d0bSHerbert Xu const u8 *buff;
444*2a598d0bSHerbert Xu mpi_limb_t a;
445*2a598d0bSHerbert Xu MPI val = NULL;
446*2a598d0bSHerbert Xu
447*2a598d0bSHerbert Xu ents = sg_nents_for_len(sgl, nbytes);
448*2a598d0bSHerbert Xu if (ents < 0)
449*2a598d0bSHerbert Xu return NULL;
450*2a598d0bSHerbert Xu
451*2a598d0bSHerbert Xu sg_miter_start(&miter, sgl, ents, SG_MITER_ATOMIC | SG_MITER_FROM_SG);
452*2a598d0bSHerbert Xu
453*2a598d0bSHerbert Xu lzeros = 0;
454*2a598d0bSHerbert Xu len = 0;
455*2a598d0bSHerbert Xu while (nbytes > 0) {
456*2a598d0bSHerbert Xu while (len && !*buff) {
457*2a598d0bSHerbert Xu lzeros++;
458*2a598d0bSHerbert Xu len--;
459*2a598d0bSHerbert Xu buff++;
460*2a598d0bSHerbert Xu }
461*2a598d0bSHerbert Xu
462*2a598d0bSHerbert Xu if (len && *buff)
463*2a598d0bSHerbert Xu break;
464*2a598d0bSHerbert Xu
465*2a598d0bSHerbert Xu sg_miter_next(&miter);
466*2a598d0bSHerbert Xu buff = miter.addr;
467*2a598d0bSHerbert Xu len = miter.length;
468*2a598d0bSHerbert Xu
469*2a598d0bSHerbert Xu nbytes -= lzeros;
470*2a598d0bSHerbert Xu lzeros = 0;
471*2a598d0bSHerbert Xu }
472*2a598d0bSHerbert Xu
473*2a598d0bSHerbert Xu miter.consumed = lzeros;
474*2a598d0bSHerbert Xu
475*2a598d0bSHerbert Xu nbytes -= lzeros;
476*2a598d0bSHerbert Xu nbits = nbytes * 8;
477*2a598d0bSHerbert Xu if (nbits > MAX_EXTERN_MPI_BITS) {
478*2a598d0bSHerbert Xu sg_miter_stop(&miter);
479*2a598d0bSHerbert Xu pr_info("MPI: mpi too large (%u bits)\n", nbits);
480*2a598d0bSHerbert Xu return NULL;
481*2a598d0bSHerbert Xu }
482*2a598d0bSHerbert Xu
483*2a598d0bSHerbert Xu if (nbytes > 0)
484*2a598d0bSHerbert Xu nbits -= count_leading_zeros(*buff) - (BITS_PER_LONG - 8);
485*2a598d0bSHerbert Xu
486*2a598d0bSHerbert Xu sg_miter_stop(&miter);
487*2a598d0bSHerbert Xu
488*2a598d0bSHerbert Xu nlimbs = DIV_ROUND_UP(nbytes, BYTES_PER_MPI_LIMB);
489*2a598d0bSHerbert Xu val = mpi_alloc(nlimbs);
490*2a598d0bSHerbert Xu if (!val)
491*2a598d0bSHerbert Xu return NULL;
492*2a598d0bSHerbert Xu
493*2a598d0bSHerbert Xu val->nbits = nbits;
494*2a598d0bSHerbert Xu val->sign = 0;
495*2a598d0bSHerbert Xu val->nlimbs = nlimbs;
496*2a598d0bSHerbert Xu
497*2a598d0bSHerbert Xu if (nbytes == 0)
498*2a598d0bSHerbert Xu return val;
499*2a598d0bSHerbert Xu
500*2a598d0bSHerbert Xu j = nlimbs - 1;
501*2a598d0bSHerbert Xu a = 0;
502*2a598d0bSHerbert Xu z = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
503*2a598d0bSHerbert Xu z %= BYTES_PER_MPI_LIMB;
504*2a598d0bSHerbert Xu
505*2a598d0bSHerbert Xu while (sg_miter_next(&miter)) {
506*2a598d0bSHerbert Xu buff = miter.addr;
507*2a598d0bSHerbert Xu len = min_t(unsigned, miter.length, nbytes);
508*2a598d0bSHerbert Xu nbytes -= len;
509*2a598d0bSHerbert Xu
510*2a598d0bSHerbert Xu for (x = 0; x < len; x++) {
511*2a598d0bSHerbert Xu a <<= 8;
512*2a598d0bSHerbert Xu a |= *buff++;
513*2a598d0bSHerbert Xu if (((z + x + 1) % BYTES_PER_MPI_LIMB) == 0) {
514*2a598d0bSHerbert Xu val->d[j--] = a;
515*2a598d0bSHerbert Xu a = 0;
516*2a598d0bSHerbert Xu }
517*2a598d0bSHerbert Xu }
518*2a598d0bSHerbert Xu z += x;
519*2a598d0bSHerbert Xu }
520*2a598d0bSHerbert Xu
521*2a598d0bSHerbert Xu return val;
522*2a598d0bSHerbert Xu }
523*2a598d0bSHerbert Xu EXPORT_SYMBOL_GPL(mpi_read_raw_from_sgl);
524*2a598d0bSHerbert Xu
525*2a598d0bSHerbert Xu /* Perform a two's complement operation on buffer P of size N bytes. */
twocompl(unsigned char * p,unsigned int n)526*2a598d0bSHerbert Xu static void twocompl(unsigned char *p, unsigned int n)
527*2a598d0bSHerbert Xu {
528*2a598d0bSHerbert Xu int i;
529*2a598d0bSHerbert Xu
530*2a598d0bSHerbert Xu for (i = n-1; i >= 0 && !p[i]; i--)
531*2a598d0bSHerbert Xu ;
532*2a598d0bSHerbert Xu if (i >= 0) {
533*2a598d0bSHerbert Xu if ((p[i] & 0x01))
534*2a598d0bSHerbert Xu p[i] = (((p[i] ^ 0xfe) | 0x01) & 0xff);
535*2a598d0bSHerbert Xu else if ((p[i] & 0x02))
536*2a598d0bSHerbert Xu p[i] = (((p[i] ^ 0xfc) | 0x02) & 0xfe);
537*2a598d0bSHerbert Xu else if ((p[i] & 0x04))
538*2a598d0bSHerbert Xu p[i] = (((p[i] ^ 0xf8) | 0x04) & 0xfc);
539*2a598d0bSHerbert Xu else if ((p[i] & 0x08))
540*2a598d0bSHerbert Xu p[i] = (((p[i] ^ 0xf0) | 0x08) & 0xf8);
541*2a598d0bSHerbert Xu else if ((p[i] & 0x10))
542*2a598d0bSHerbert Xu p[i] = (((p[i] ^ 0xe0) | 0x10) & 0xf0);
543*2a598d0bSHerbert Xu else if ((p[i] & 0x20))
544*2a598d0bSHerbert Xu p[i] = (((p[i] ^ 0xc0) | 0x20) & 0xe0);
545*2a598d0bSHerbert Xu else if ((p[i] & 0x40))
546*2a598d0bSHerbert Xu p[i] = (((p[i] ^ 0x80) | 0x40) & 0xc0);
547*2a598d0bSHerbert Xu else
548*2a598d0bSHerbert Xu p[i] = 0x80;
549*2a598d0bSHerbert Xu
550*2a598d0bSHerbert Xu for (i--; i >= 0; i--)
551*2a598d0bSHerbert Xu p[i] ^= 0xff;
552*2a598d0bSHerbert Xu }
553*2a598d0bSHerbert Xu }
554*2a598d0bSHerbert Xu
mpi_print(enum gcry_mpi_format format,unsigned char * buffer,size_t buflen,size_t * nwritten,MPI a)555*2a598d0bSHerbert Xu int mpi_print(enum gcry_mpi_format format, unsigned char *buffer,
556*2a598d0bSHerbert Xu size_t buflen, size_t *nwritten, MPI a)
557*2a598d0bSHerbert Xu {
558*2a598d0bSHerbert Xu unsigned int nbits = mpi_get_nbits(a);
559*2a598d0bSHerbert Xu size_t len;
560*2a598d0bSHerbert Xu size_t dummy_nwritten;
561*2a598d0bSHerbert Xu int negative;
562*2a598d0bSHerbert Xu
563*2a598d0bSHerbert Xu if (!nwritten)
564*2a598d0bSHerbert Xu nwritten = &dummy_nwritten;
565*2a598d0bSHerbert Xu
566*2a598d0bSHerbert Xu /* Libgcrypt does no always care to set clear the sign if the value
567*2a598d0bSHerbert Xu * is 0. For printing this is a bit of a surprise, in particular
568*2a598d0bSHerbert Xu * because if some of the formats don't support negative numbers but
569*2a598d0bSHerbert Xu * should be able to print a zero. Thus we need this extra test
570*2a598d0bSHerbert Xu * for a negative number.
571*2a598d0bSHerbert Xu */
572*2a598d0bSHerbert Xu if (a->sign && mpi_cmp_ui(a, 0))
573*2a598d0bSHerbert Xu negative = 1;
574*2a598d0bSHerbert Xu else
575*2a598d0bSHerbert Xu negative = 0;
576*2a598d0bSHerbert Xu
577*2a598d0bSHerbert Xu len = buflen;
578*2a598d0bSHerbert Xu *nwritten = 0;
579*2a598d0bSHerbert Xu if (format == GCRYMPI_FMT_STD) {
580*2a598d0bSHerbert Xu unsigned char *tmp;
581*2a598d0bSHerbert Xu int extra = 0;
582*2a598d0bSHerbert Xu unsigned int n;
583*2a598d0bSHerbert Xu
584*2a598d0bSHerbert Xu tmp = mpi_get_buffer(a, &n, NULL);
585*2a598d0bSHerbert Xu if (!tmp)
586*2a598d0bSHerbert Xu return -EINVAL;
587*2a598d0bSHerbert Xu
588*2a598d0bSHerbert Xu if (negative) {
589*2a598d0bSHerbert Xu twocompl(tmp, n);
590*2a598d0bSHerbert Xu if (!(*tmp & 0x80)) {
591*2a598d0bSHerbert Xu /* Need to extend the sign. */
592*2a598d0bSHerbert Xu n++;
593*2a598d0bSHerbert Xu extra = 2;
594*2a598d0bSHerbert Xu }
595*2a598d0bSHerbert Xu } else if (n && (*tmp & 0x80)) {
596*2a598d0bSHerbert Xu /* Positive but the high bit of the returned buffer is set.
597*2a598d0bSHerbert Xu * Thus we need to print an extra leading 0x00 so that the
598*2a598d0bSHerbert Xu * output is interpreted as a positive number.
599*2a598d0bSHerbert Xu */
600*2a598d0bSHerbert Xu n++;
601*2a598d0bSHerbert Xu extra = 1;
602*2a598d0bSHerbert Xu }
603*2a598d0bSHerbert Xu
604*2a598d0bSHerbert Xu if (buffer && n > len) {
605*2a598d0bSHerbert Xu /* The provided buffer is too short. */
606*2a598d0bSHerbert Xu kfree(tmp);
607*2a598d0bSHerbert Xu return -E2BIG;
608*2a598d0bSHerbert Xu }
609*2a598d0bSHerbert Xu if (buffer) {
610*2a598d0bSHerbert Xu unsigned char *s = buffer;
611*2a598d0bSHerbert Xu
612*2a598d0bSHerbert Xu if (extra == 1)
613*2a598d0bSHerbert Xu *s++ = 0;
614*2a598d0bSHerbert Xu else if (extra)
615*2a598d0bSHerbert Xu *s++ = 0xff;
616*2a598d0bSHerbert Xu memcpy(s, tmp, n-!!extra);
617*2a598d0bSHerbert Xu }
618*2a598d0bSHerbert Xu kfree(tmp);
619*2a598d0bSHerbert Xu *nwritten = n;
620*2a598d0bSHerbert Xu return 0;
621*2a598d0bSHerbert Xu } else if (format == GCRYMPI_FMT_USG) {
622*2a598d0bSHerbert Xu unsigned int n = (nbits + 7)/8;
623*2a598d0bSHerbert Xu
624*2a598d0bSHerbert Xu /* Note: We ignore the sign for this format. */
625*2a598d0bSHerbert Xu /* FIXME: for performance reasons we should put this into
626*2a598d0bSHerbert Xu * mpi_aprint because we can then use the buffer directly.
627*2a598d0bSHerbert Xu */
628*2a598d0bSHerbert Xu
629*2a598d0bSHerbert Xu if (buffer && n > len)
630*2a598d0bSHerbert Xu return -E2BIG;
631*2a598d0bSHerbert Xu if (buffer) {
632*2a598d0bSHerbert Xu unsigned char *tmp;
633*2a598d0bSHerbert Xu
634*2a598d0bSHerbert Xu tmp = mpi_get_buffer(a, &n, NULL);
635*2a598d0bSHerbert Xu if (!tmp)
636*2a598d0bSHerbert Xu return -EINVAL;
637*2a598d0bSHerbert Xu memcpy(buffer, tmp, n);
638*2a598d0bSHerbert Xu kfree(tmp);
639*2a598d0bSHerbert Xu }
640*2a598d0bSHerbert Xu *nwritten = n;
641*2a598d0bSHerbert Xu return 0;
642*2a598d0bSHerbert Xu } else if (format == GCRYMPI_FMT_PGP) {
643*2a598d0bSHerbert Xu unsigned int n = (nbits + 7)/8;
644*2a598d0bSHerbert Xu
645*2a598d0bSHerbert Xu /* The PGP format can only handle unsigned integers. */
646*2a598d0bSHerbert Xu if (negative)
647*2a598d0bSHerbert Xu return -EINVAL;
648*2a598d0bSHerbert Xu
649*2a598d0bSHerbert Xu if (buffer && n+2 > len)
650*2a598d0bSHerbert Xu return -E2BIG;
651*2a598d0bSHerbert Xu
652*2a598d0bSHerbert Xu if (buffer) {
653*2a598d0bSHerbert Xu unsigned char *tmp;
654*2a598d0bSHerbert Xu unsigned char *s = buffer;
655*2a598d0bSHerbert Xu
656*2a598d0bSHerbert Xu s[0] = nbits >> 8;
657*2a598d0bSHerbert Xu s[1] = nbits;
658*2a598d0bSHerbert Xu
659*2a598d0bSHerbert Xu tmp = mpi_get_buffer(a, &n, NULL);
660*2a598d0bSHerbert Xu if (!tmp)
661*2a598d0bSHerbert Xu return -EINVAL;
662*2a598d0bSHerbert Xu memcpy(s+2, tmp, n);
663*2a598d0bSHerbert Xu kfree(tmp);
664*2a598d0bSHerbert Xu }
665*2a598d0bSHerbert Xu *nwritten = n+2;
666*2a598d0bSHerbert Xu return 0;
667*2a598d0bSHerbert Xu } else if (format == GCRYMPI_FMT_SSH) {
668*2a598d0bSHerbert Xu unsigned char *tmp;
669*2a598d0bSHerbert Xu int extra = 0;
670*2a598d0bSHerbert Xu unsigned int n;
671*2a598d0bSHerbert Xu
672*2a598d0bSHerbert Xu tmp = mpi_get_buffer(a, &n, NULL);
673*2a598d0bSHerbert Xu if (!tmp)
674*2a598d0bSHerbert Xu return -EINVAL;
675*2a598d0bSHerbert Xu
676*2a598d0bSHerbert Xu if (negative) {
677*2a598d0bSHerbert Xu twocompl(tmp, n);
678*2a598d0bSHerbert Xu if (!(*tmp & 0x80)) {
679*2a598d0bSHerbert Xu /* Need to extend the sign. */
680*2a598d0bSHerbert Xu n++;
681*2a598d0bSHerbert Xu extra = 2;
682*2a598d0bSHerbert Xu }
683*2a598d0bSHerbert Xu } else if (n && (*tmp & 0x80)) {
684*2a598d0bSHerbert Xu n++;
685*2a598d0bSHerbert Xu extra = 1;
686*2a598d0bSHerbert Xu }
687*2a598d0bSHerbert Xu
688*2a598d0bSHerbert Xu if (buffer && n+4 > len) {
689*2a598d0bSHerbert Xu kfree(tmp);
690*2a598d0bSHerbert Xu return -E2BIG;
691*2a598d0bSHerbert Xu }
692*2a598d0bSHerbert Xu
693*2a598d0bSHerbert Xu if (buffer) {
694*2a598d0bSHerbert Xu unsigned char *s = buffer;
695*2a598d0bSHerbert Xu
696*2a598d0bSHerbert Xu *s++ = n >> 24;
697*2a598d0bSHerbert Xu *s++ = n >> 16;
698*2a598d0bSHerbert Xu *s++ = n >> 8;
699*2a598d0bSHerbert Xu *s++ = n;
700*2a598d0bSHerbert Xu if (extra == 1)
701*2a598d0bSHerbert Xu *s++ = 0;
702*2a598d0bSHerbert Xu else if (extra)
703*2a598d0bSHerbert Xu *s++ = 0xff;
704*2a598d0bSHerbert Xu memcpy(s, tmp, n-!!extra);
705*2a598d0bSHerbert Xu }
706*2a598d0bSHerbert Xu kfree(tmp);
707*2a598d0bSHerbert Xu *nwritten = 4+n;
708*2a598d0bSHerbert Xu return 0;
709*2a598d0bSHerbert Xu } else if (format == GCRYMPI_FMT_HEX) {
710*2a598d0bSHerbert Xu unsigned char *tmp;
711*2a598d0bSHerbert Xu int i;
712*2a598d0bSHerbert Xu int extra = 0;
713*2a598d0bSHerbert Xu unsigned int n = 0;
714*2a598d0bSHerbert Xu
715*2a598d0bSHerbert Xu tmp = mpi_get_buffer(a, &n, NULL);
716*2a598d0bSHerbert Xu if (!tmp)
717*2a598d0bSHerbert Xu return -EINVAL;
718*2a598d0bSHerbert Xu if (!n || (*tmp & 0x80))
719*2a598d0bSHerbert Xu extra = 2;
720*2a598d0bSHerbert Xu
721*2a598d0bSHerbert Xu if (buffer && 2*n + extra + negative + 1 > len) {
722*2a598d0bSHerbert Xu kfree(tmp);
723*2a598d0bSHerbert Xu return -E2BIG;
724*2a598d0bSHerbert Xu }
725*2a598d0bSHerbert Xu if (buffer) {
726*2a598d0bSHerbert Xu unsigned char *s = buffer;
727*2a598d0bSHerbert Xu
728*2a598d0bSHerbert Xu if (negative)
729*2a598d0bSHerbert Xu *s++ = '-';
730*2a598d0bSHerbert Xu if (extra) {
731*2a598d0bSHerbert Xu *s++ = '0';
732*2a598d0bSHerbert Xu *s++ = '0';
733*2a598d0bSHerbert Xu }
734*2a598d0bSHerbert Xu
735*2a598d0bSHerbert Xu for (i = 0; i < n; i++) {
736*2a598d0bSHerbert Xu unsigned int c = tmp[i];
737*2a598d0bSHerbert Xu
738*2a598d0bSHerbert Xu *s++ = (c >> 4) < 10 ? '0'+(c>>4) : 'A'+(c>>4)-10;
739*2a598d0bSHerbert Xu c &= 15;
740*2a598d0bSHerbert Xu *s++ = c < 10 ? '0'+c : 'A'+c-10;
741*2a598d0bSHerbert Xu }
742*2a598d0bSHerbert Xu *s++ = 0;
743*2a598d0bSHerbert Xu *nwritten = s - buffer;
744*2a598d0bSHerbert Xu } else {
745*2a598d0bSHerbert Xu *nwritten = 2*n + extra + negative + 1;
746*2a598d0bSHerbert Xu }
747*2a598d0bSHerbert Xu kfree(tmp);
748*2a598d0bSHerbert Xu return 0;
749*2a598d0bSHerbert Xu } else
750*2a598d0bSHerbert Xu return -EINVAL;
751*2a598d0bSHerbert Xu }
752*2a598d0bSHerbert Xu EXPORT_SYMBOL_GPL(mpi_print);
753