1
/* mpicoder.c - Coder for the external representation of MPIs
2
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
4
* This file is part of GnuPG.
6
* GnuPG is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* GnuPG is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
28
#include "mpi-internal.h"
37
#define MAX_EXTERN_MPI_BITS 16384
40
* write an mpi to out.
43
mpi_write( IOBUF out, MPI a )
46
unsigned nbits = mpi_get_nbits(a);
50
if( nbits > MAX_EXTERN_MPI_BITS )
51
log_bug("mpi_encode: mpi too large (%u bits)\n", nbits);
53
iobuf_put(out, (nbits >>8) );
54
iobuf_put(out, (nbits) );
56
p = buf = mpi_get_buffer( a, &n, NULL );
57
rc = iobuf_write( out, p, n );
64
* Read an external representation of an mpi and return the MPI
65
* The external format is a 16 bit unsigned value stored in network byte order,
66
* giving the number of bits for the following integer. The integer is stored
67
* with MSB first (left padded with zeroes to align on a byte boundary).
71
mpi_debug_read(IOBUF inp, unsigned *ret_nread, int secure, const char *info)
73
mpi_read(IOBUF inp, unsigned *ret_nread, int secure)
77
unsigned nbits, nbytes, nlimbs, nread=0;
81
if( (c = iobuf_get(inp)) == -1 )
85
if( (c = iobuf_get(inp)) == -1 )
89
if( nbits > MAX_EXTERN_MPI_BITS ) {
90
log_error("mpi too large (%u bits)\n", nbits);
94
nbytes = (nbits+7) / 8;
95
nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
97
val = secure? mpi_debug_alloc_secure( nlimbs, info )
98
: mpi_debug_alloc( nlimbs, info );
100
val = secure? mpi_alloc_secure( nlimbs )
101
: mpi_alloc( nlimbs );
103
i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
104
i %= BYTES_PER_MPI_LIMB;
106
j= val->nlimbs = nlimbs;
108
for( ; j > 0; j-- ) {
110
for(; i < BYTES_PER_MPI_LIMB; i++ ) {
112
a |= iobuf_get(inp) & 0xff; nread++;
119
if( nread > *ret_nread )
120
log_bug("mpi crosses packet border\n");
128
mpi_read_from_buffer(byte *buffer, unsigned int *ret_nread, int secure)
131
unsigned nbits, nbytes, nlimbs, nread=0;
137
nbits = buffer[0] << 8 | buffer[1];
138
if( nbits > MAX_EXTERN_MPI_BITS ) {
139
log_info ("mpi too large (%u bits)\n", nbits);
145
nbytes = (nbits+7) / 8;
146
nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
147
val = secure? mpi_alloc_secure( nlimbs )
148
: mpi_alloc( nlimbs );
149
i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
150
i %= BYTES_PER_MPI_LIMB;
152
j= val->nlimbs = nlimbs;
154
for( ; j > 0; j-- ) {
156
for(; i < BYTES_PER_MPI_LIMB; i++ ) {
157
if( ++nread > *ret_nread ) {
158
/* This (as well as the above error condition) may
159
happen if we use this function to parse a decrypted
160
MPI which didn't turn out to be a real MPI - possible
161
because the supplied key was wrong but the OpenPGP
162
checksum didn't caught it. */
163
log_info ("mpi larger than buffer\n");
182
* Make an mpi from a character string.
185
mpi_fromstr(MPI val, const char *str)
187
int hexmode=0, sign=0, prepend_zero=0, i, j, c, c1, c2;
188
unsigned nbits, nbytes, nlimbs;
195
if( *str == '0' && str[1] == 'x' )
198
return 1; /* other bases are not yet supported */
201
nbits = strlen(str)*4;
204
nbytes = (nbits+7) / 8;
205
nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
206
if( val->alloced < nlimbs )
207
mpi_resize(val, nlimbs );
208
i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
209
i %= BYTES_PER_MPI_LIMB;
210
j= val->nlimbs = nlimbs;
212
for( ; j > 0; j-- ) {
214
for(; i < BYTES_PER_MPI_LIMB; i++ ) {
224
if( c1 >= '0' && c1 <= '9' )
226
else if( c1 >= 'a' && c1 <= 'f' )
228
else if( c1 >= 'A' && c1 <= 'F' )
235
if( c2 >= '0' && c2 <= '9' )
237
else if( c2 >= 'a' && c2 <= 'f' )
239
else if( c2 >= 'A' && c2 <= 'F' )
257
* print an MPI to the given stream and return the number of characters
261
mpi_print( FILE *fp, MPI a, int mode )
266
return fprintf(fp, "[MPI_NULL]");
270
n1 = mpi_get_nbits(a);
271
n += fprintf(fp, "[%u bits]", n1);
276
#if BYTES_PER_MPI_LIMB == 2
278
#elif BYTES_PER_MPI_LIMB == 4
280
#elif BYTES_PER_MPI_LIMB == 8
283
#error please define the format here
285
for(i=a->nlimbs; i > 0 ; i-- ) {
286
n += fprintf(fp, i!=a->nlimbs? "%0" X "lX":"%lX", (ulong)a->d[i-1]);
297
g10_log_mpidump( const char *text, MPI a )
299
FILE *fp = log_stream();
301
g10_log_print_prefix(text);
302
mpi_print(fp, a, 1 );
307
* Special function to get the low 8 bytes from an mpi.
308
* This can be used as a keyid; KEYID is an 2 element array.
309
* Return the low 4 bytes.
312
mpi_get_keyid( MPI a, u32 *keyid )
314
#if BYTES_PER_MPI_LIMB == 4
316
keyid[0] = a->nlimbs >= 2? a->d[1] : 0;
317
keyid[1] = a->nlimbs >= 1? a->d[0] : 0;
319
return a->nlimbs >= 1? a->d[0] : 0;
320
#elif BYTES_PER_MPI_LIMB == 8
322
keyid[0] = a->nlimbs? (u32)(a->d[0] >> 32) : 0;
323
keyid[1] = a->nlimbs? (u32)(a->d[0] & 0xffffffff) : 0;
325
return a->nlimbs? (u32)(a->d[0] & 0xffffffff) : 0;
327
#error Make this function work with other LIMB sizes
333
* Return an m_alloced buffer with the MPI (msb first).
334
* NBYTES receives the length of this buffer. Caller must free the
335
* return string (This function does return a 0 byte buffer with NBYTES
336
* set to zero if the value of A is zero. If sign is not NULL, it will
337
* be set to the sign of the A.
340
do_get_buffer( MPI a, unsigned *nbytes, int *sign, int force_secure )
349
*nbytes = n = a->nlimbs * BYTES_PER_MPI_LIMB;
351
n++; /* avoid zero length allocation */
352
p = buffer = force_secure || mpi_is_secure(a) ? m_alloc_secure(n)
355
for(i=a->nlimbs-1; i >= 0; i-- ) {
357
#if BYTES_PER_MPI_LIMB == 4
362
#elif BYTES_PER_MPI_LIMB == 8
372
#error please implement for this limb size.
376
/* this is sub-optimal but we need to do the shift operation
377
* because the caller has to free the returned buffer */
378
for(p=buffer; !*p && *nbytes; p++, --*nbytes )
381
memmove(buffer,p, *nbytes);
388
mpi_get_buffer( MPI a, unsigned *nbytes, int *sign )
390
return do_get_buffer( a, nbytes, sign, 0 );
394
mpi_get_secure_buffer( MPI a, unsigned *nbytes, int *sign )
396
return do_get_buffer( a, nbytes, sign, 1 );
400
* Use BUFFER to update MPI.
403
mpi_set_buffer( MPI a, const byte *buffer, unsigned nbytes, int sign )
410
nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
411
RESIZE_IF_NEEDED(a, nlimbs);
414
for(i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; ) {
415
#if BYTES_PER_MPI_LIMB == 4
416
alimb = (mpi_limb_t)*p-- ;
417
alimb |= (mpi_limb_t)*p-- << 8 ;
418
alimb |= (mpi_limb_t)*p-- << 16 ;
419
alimb |= (mpi_limb_t)*p-- << 24 ;
420
#elif BYTES_PER_MPI_LIMB == 8
421
alimb = (mpi_limb_t)*p-- ;
422
alimb |= (mpi_limb_t)*p-- << 8 ;
423
alimb |= (mpi_limb_t)*p-- << 16 ;
424
alimb |= (mpi_limb_t)*p-- << 24 ;
425
alimb |= (mpi_limb_t)*p-- << 32 ;
426
alimb |= (mpi_limb_t)*p-- << 40 ;
427
alimb |= (mpi_limb_t)*p-- << 48 ;
428
alimb |= (mpi_limb_t)*p-- << 56 ;
430
#error please implement for this limb size.
435
#if BYTES_PER_MPI_LIMB == 4
437
if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 8 ;
438
if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 16 ;
439
if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 24 ;
440
#elif BYTES_PER_MPI_LIMB == 8
441
alimb = (mpi_limb_t)*p-- ;
442
if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 8 ;
443
if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 16 ;
444
if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 24 ;
445
if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 32 ;
446
if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 40 ;
447
if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 48 ;
448
if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 56 ;
450
#error please implement for this limb size.
455
assert( i == nlimbs );