209
* Return an m_alloced buffer with the MPI (msb first).
210
* NBYTES receives the length of this buffer. Caller must free the
211
* return string (This function does return a 0 byte buffer with NBYTES
212
* set to zero if the value of A is zero. If sign is not NULL, it will
213
* be set to the sign of the A.
216
do_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign, int force_secure )
230
/* Return an allocated buffer with the MPI (msb first). NBYTES
231
receives the length of this buffer. Caller must free the return
232
string. This function returns an allocated buffer with NBYTES set
233
to zero if the value of A is zero. If sign is not NULL, it will be
234
set to the sign of the A. On error NULL is returned and ERRNO set
236
static unsigned char *
237
do_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign, int force_secure)
225
*nbytes = a->nlimbs * BYTES_PER_MPI_LIMB;
226
n = *nbytes? *nbytes:1; /* allocate at least one byte */
227
p = buffer = force_secure || mpi_is_secure(a) ? gcry_xmalloc_secure(n)
230
for(i=a->nlimbs-1; i >= 0; i-- ) {
239
unsigned char *p, *buffer;
247
*nbytes = a->nlimbs * BYTES_PER_MPI_LIMB;
248
n = *nbytes? *nbytes:1; /* Allocate at least one byte. */
249
p = buffer = (force_secure || mpi_is_secure(a))? gcry_malloc_secure (n)
254
for (i=a->nlimbs-1; i >= 0; i--)
232
257
#if BYTES_PER_MPI_LIMB == 4
237
262
#elif BYTES_PER_MPI_LIMB == 8
247
#error please implement for this limb size.
272
# error please implement for this limb size.
251
/* this is sub-optimal but we need to do the shift oepration because
252
* the caller has to free the returned buffer */
253
for(p=buffer; !*p && *nbytes; p++, --*nbytes )
256
memmove(buffer,p, *nbytes);
262
_gcry_mpi_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign )
264
return do_get_buffer( a, nbytes, sign, 0 );
268
_gcry_mpi_get_secure_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign )
270
return do_get_buffer( a, nbytes, sign, 1 );
274
* Use BUFFER to update MPI.
276
/* This is sub-optimal but we need to do the shift operation because
277
the caller has to free the returned buffer. */
278
for (p=buffer; !*p && *nbytes; p++, --*nbytes)
281
memmove (buffer,p, *nbytes);
287
_gcry_mpi_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign)
289
return do_get_buffer (a, nbytes, sign, 0);
293
_gcry_mpi_get_secure_buffer (gcry_mpi_t a, unsigned *nbytes, int *sign)
295
return do_get_buffer (a, nbytes, sign, 1);
300
* Use the NBYTES at BUFFER_ARG to update A. Set the sign of a to
277
_gcry_mpi_set_buffer ( gcry_mpi_t a, const void *buffer_arg,
278
unsigned int nbytes, int sign )
304
_gcry_mpi_set_buffer (gcry_mpi_t a, const void *buffer_arg,
305
unsigned int nbytes, int sign)
280
const unsigned char *buffer = (const unsigned char*)buffer_arg;
286
nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
287
RESIZE_IF_NEEDED(a, nlimbs);
290
for(i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; ) {
291
#if BYTES_PER_MPI_LIMB == 4
294
alimb |= *p-- << 16 ;
295
alimb |= *p-- << 24 ;
296
#elif BYTES_PER_MPI_LIMB == 8
297
alimb = (mpi_limb_t)*p-- ;
298
alimb |= (mpi_limb_t)*p-- << 8 ;
299
alimb |= (mpi_limb_t)*p-- << 16 ;
300
alimb |= (mpi_limb_t)*p-- << 24 ;
301
alimb |= (mpi_limb_t)*p-- << 32 ;
302
alimb |= (mpi_limb_t)*p-- << 40 ;
303
alimb |= (mpi_limb_t)*p-- << 48 ;
304
alimb |= (mpi_limb_t)*p-- << 56 ;
306
#error please implement for this limb size.
311
#if BYTES_PER_MPI_LIMB == 4
313
if( p >= buffer ) alimb |= *p-- << 8 ;
314
if( p >= buffer ) alimb |= *p-- << 16 ;
315
if( p >= buffer ) alimb |= *p-- << 24 ;
316
#elif BYTES_PER_MPI_LIMB == 8
317
alimb = (mpi_limb_t)*p-- ;
318
if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 8 ;
319
if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 16 ;
320
if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 24 ;
321
if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 32 ;
322
if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 40 ;
323
if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 48 ;
324
if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 56 ;
326
#error please implement for this limb size.
331
assert( i == nlimbs );
307
const unsigned char *buffer = (const unsigned char*)buffer_arg;
308
const unsigned char *p;
313
nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
314
RESIZE_IF_NEEDED(a, nlimbs);
317
for (i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; )
319
#if BYTES_PER_MPI_LIMB == 4
322
alimb |= *p-- << 16 ;
323
alimb |= *p-- << 24 ;
324
#elif BYTES_PER_MPI_LIMB == 8
325
alimb = (mpi_limb_t)*p-- ;
326
alimb |= (mpi_limb_t)*p-- << 8 ;
327
alimb |= (mpi_limb_t)*p-- << 16 ;
328
alimb |= (mpi_limb_t)*p-- << 24 ;
329
alimb |= (mpi_limb_t)*p-- << 32 ;
330
alimb |= (mpi_limb_t)*p-- << 40 ;
331
alimb |= (mpi_limb_t)*p-- << 48 ;
332
alimb |= (mpi_limb_t)*p-- << 56 ;
334
# error please implement for this limb size.
340
#if BYTES_PER_MPI_LIMB == 4
348
#elif BYTES_PER_MPI_LIMB == 8
349
alimb = (mpi_limb_t)*p--;
351
alimb |= (mpi_limb_t)*p-- << 8;
353
alimb |= (mpi_limb_t)*p-- << 16;
355
alimb |= (mpi_limb_t)*p-- << 24;
357
alimb |= (mpi_limb_t)*p-- << 32;
359
alimb |= (mpi_limb_t)*p-- << 40;
361
alimb |= (mpi_limb_t)*p-- << 48;
363
alimb |= (mpi_limb_t)*p-- << 56;
365
# error please implement for this limb size.
370
gcry_assert (i == nlimbs);
336
374
/* Convert the external representation of an integer stored in BUFFER
337
375
with a length of BUFLEN into a newly create MPI returned in
338
376
RET_MPI. If NBYTES is not NULL, it will receive the number of
339
bytes actually scanned after a successful operation. */
377
bytes actually scanned after a successful operation. */
341
gcry_mpi_scan( struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
342
const void *buffer_arg, size_t buflen, size_t *nscanned )
379
gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
380
const void *buffer_arg, size_t buflen, size_t *nscanned)
344
const unsigned char *buffer = (const unsigned char*)buffer_arg;
345
struct gcry_mpi *a = NULL;
347
int secure = (buffer && gcry_is_secure (buffer));
349
if (format == GCRYMPI_FMT_SSH)
354
if( format == GCRYMPI_FMT_STD ) {
355
const byte *s = buffer;
357
a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
359
: mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
360
if( len ) { /* not zero */
363
/* FIXME: we have to convert from 2compl to magnitude format */
365
return gcry_error (GPG_ERR_INTERNAL);
368
_gcry_mpi_set_buffer( a, s, len, 0 );
376
return gcry_error (GPG_ERR_NO_ERROR);
378
else if( format == GCRYMPI_FMT_USG ) {
379
a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
381
: mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
383
if( len ) /* not zero */
384
_gcry_mpi_set_buffer( a, buffer, len, 0 );
391
return gcry_error (GPG_ERR_NO_ERROR);
393
else if( format == GCRYMPI_FMT_PGP ) {
394
a = mpi_read_from_buffer (buffer, &len, secure);
403
return gcry_error (a ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ);
405
else if( format == GCRYMPI_FMT_SSH ) {
406
const unsigned char *s = buffer;
410
return gcry_error (GPG_ERR_TOO_SHORT);
411
n = s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
416
return gcry_error (GPG_ERR_TOO_LARGE); /* or should it be
419
a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1)
421
: mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
422
if( n ) { /* not zero */
425
/* FIXME: we have to convert from 2compl to magnitude format */
427
return gcry_error (GPG_ERR_INTERNAL);
430
_gcry_mpi_set_buffer( a, s, n, 0 );
440
return gcry_error (GPG_ERR_NO_ERROR);
442
else if( format == GCRYMPI_FMT_HEX ) {
444
return gcry_error (GPG_ERR_INV_ARG); /* can only handle C
446
a = secure? mpi_alloc_secure (0) : mpi_alloc(0);
447
if( mpi_fromstr ( a, (const char *)buffer ) )
448
return gcry_error (GPG_ERR_INV_OBJ);
455
return gcry_error (GPG_ERR_NO_ERROR);
458
return gcry_error (GPG_ERR_INV_ARG);
382
const unsigned char *buffer = (const unsigned char*)buffer_arg;
383
struct gcry_mpi *a = NULL;
385
int secure = (buffer && gcry_is_secure (buffer));
387
if (format == GCRYMPI_FMT_SSH)
392
if (format == GCRYMPI_FMT_STD)
394
const unsigned char *s = buffer;
396
a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
398
: mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
401
a->sign = !!(*s & 0x80);
404
/* FIXME: we have to convert from 2compl to magnitude format */
406
return gcry_error (GPG_ERR_INTERNAL);
409
_gcry_mpi_set_buffer (a, s, len, 0);
420
else if (format == GCRYMPI_FMT_USG)
422
a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
424
: mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
427
_gcry_mpi_set_buffer (a, buffer, len, 0);
437
else if (format == GCRYMPI_FMT_PGP)
439
a = mpi_read_from_buffer (buffer, &len, secure);
452
return a? 0 : gcry_error (GPG_ERR_INV_OBJ);
454
else if (format == GCRYMPI_FMT_SSH)
456
const unsigned char *s = buffer;
460
return gcry_error (GPG_ERR_TOO_SHORT);
462
n = (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
467
return gcry_error (GPG_ERR_TOO_LARGE);
469
a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1)
471
: mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
474
a->sign = !!(*s & 0x80);
477
/* FIXME: we have to convert from 2compl to magnitude format */
479
return gcry_error (GPG_ERR_INTERNAL);
482
_gcry_mpi_set_buffer( a, s, n, 0 );
495
else if (format == GCRYMPI_FMT_HEX)
497
/* We can only handle C strings for now. */
499
return gcry_error (GPG_ERR_INV_ARG);
501
a = secure? mpi_alloc_secure (0) : mpi_alloc(0);
502
if (mpi_fromstr (a, (const char *)buffer))
505
return gcry_error (GPG_ERR_INV_OBJ);
517
return gcry_error (GPG_ERR_INV_ARG);
461
521
/* Convert the big integer A into the external representation
462
522
described by FORMAT and store it in the provided BUFFER which has
463
523
been allocated by the user with a size of BUFLEN bytes. NWRITTEN
464
524
receives the actual length of the external representation unless it
465
525
has been passed as NULL. BUFFER may be NULL to query the required
468
gcry_mpi_print( enum gcry_mpi_format format,
528
gcry_mpi_print (enum gcry_mpi_format format,
469
529
unsigned char *buffer, size_t buflen,
470
530
size_t *nwritten, struct gcry_mpi *a)
472
unsigned int nbits = mpi_get_nbits(a);
474
size_t dummy_nwritten;
477
nwritten = &dummy_nwritten;
481
if( format == GCRYMPI_FMT_STD ) {
487
return gcry_error (GPG_ERR_INTERNAL); /* can't handle it yet */
489
tmp = _gcry_mpi_get_buffer( a, &n, NULL );
490
if( n && (*tmp & 0x80) ) {
495
if (buffer && n > len) {
496
/* The provided buffer is too short. */
498
return gcry_error (GPG_ERR_TOO_SHORT);
501
unsigned char *s = buffer;
505
memcpy( s, tmp, n-extra );
509
return gcry_error (GPG_ERR_NO_ERROR);
511
else if( format == GCRYMPI_FMT_USG ) {
512
unsigned int n = (nbits + 7)/8;
514
/* we ignore the sign for this format */
515
/* FIXME: for performance reasons we should put this into
516
* mpi_aprint becuase we can then use the buffer directly */
517
if (buffer && n > len)
518
return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */
521
tmp = _gcry_mpi_get_buffer( a, &n, NULL );
522
memcpy( buffer, tmp, n );
526
return gcry_error (GPG_ERR_NO_ERROR);
528
else if( format == GCRYMPI_FMT_PGP ) {
529
unsigned int n = (nbits + 7)/8;
532
return gcry_error (GPG_ERR_INV_ARG); /* pgp format can only handle unsigned */
534
if (buffer && n+2 > len)
535
return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */
538
unsigned char *s = buffer;
542
tmp = _gcry_mpi_get_buffer( a, &n, NULL );
543
memcpy( s+2, tmp, n );
547
return gcry_error (GPG_ERR_NO_ERROR);
549
else if( format == GCRYMPI_FMT_SSH ) {
555
return gcry_error (GPG_ERR_INTERNAL); /* can't handle it yet */
557
tmp = _gcry_mpi_get_buffer( a, &n, NULL );
558
if( n && (*tmp & 0x80) ) {
563
if (buffer && n+4 > len) {
565
return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */
576
memcpy( s, tmp, n-extra );
580
return gcry_error (GPG_ERR_NO_ERROR);
582
else if( format == GCRYMPI_FMT_HEX ) {
588
tmp = _gcry_mpi_get_buffer( a, &n, NULL );
589
if( !n || (*tmp & 0x80) )
592
if(buffer && 2*n + extra + !!a->sign + 1 > len) {
594
return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */
605
for(i=0; i < n; i++ ) {
606
unsigned int c = tmp[i];
607
*s++ = (c >> 4) < 10? '0'+(c>>4) : 'A'+(c>>4)-10 ;
609
*s++ = c < 10? '0'+c : 'A'+c-10 ;
612
*nwritten = s - buffer;
615
*nwritten = 2*n + extra + !!a->sign + 1;
618
return gcry_error (GPG_ERR_NO_ERROR);
621
return gcry_error (GPG_ERR_INV_ARG);
532
unsigned int nbits = mpi_get_nbits (a);
534
size_t dummy_nwritten;
537
nwritten = &dummy_nwritten;
541
if (format == GCRYMPI_FMT_STD)
548
return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */
550
tmp = _gcry_mpi_get_buffer (a, &n, NULL);
552
return gpg_error_from_syserror ();
553
if (n && (*tmp & 0x80))
559
if (buffer && n > len)
561
/* The provided buffer is too short. */
563
return gcry_error (GPG_ERR_TOO_SHORT);
567
unsigned char *s = buffer;
571
memcpy (s, tmp, n-extra);
577
else if (format == GCRYMPI_FMT_USG)
579
unsigned int n = (nbits + 7)/8;
581
/* Note: We ignore the sign for this format. */
582
/* FIXME: for performance reasons we should put this into
583
mpi_aprint because we can then use the buffer directly. */
584
if (buffer && n > len)
585
return gcry_error (GPG_ERR_TOO_SHORT);
590
tmp = _gcry_mpi_get_buffer (a, &n, NULL);
592
return gpg_error_from_syserror ();
593
memcpy (buffer, tmp, n);
599
else if (format == GCRYMPI_FMT_PGP)
601
unsigned int n = (nbits + 7)/8;
603
/* The PGP format can only handle unsigned integers. */
605
return gcry_error (GPG_ERR_INV_ARG);
607
if (buffer && n+2 > len)
608
return gcry_error (GPG_ERR_TOO_SHORT);
613
unsigned char *s = buffer;
618
tmp = _gcry_mpi_get_buffer (a, &n, NULL);
620
return gpg_error_from_syserror ();
621
memcpy (s+2, tmp, n);
627
else if (format == GCRYMPI_FMT_SSH)
634
return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */
636
tmp = _gcry_mpi_get_buffer (a, &n, NULL);
638
return gpg_error_from_syserror ();
639
if (n && (*tmp & 0x80))
645
if (buffer && n+4 > len)
648
return gcry_error (GPG_ERR_TOO_SHORT);
653
unsigned char *s = buffer;
662
memcpy (s, tmp, n-extra);
668
else if (format == GCRYMPI_FMT_HEX)
675
tmp = _gcry_mpi_get_buffer (a, &n, NULL);
677
return gpg_error_from_syserror ();
678
if (!n || (*tmp & 0x80))
681
if (buffer && 2*n + extra + !!a->sign + 1 > len)
684
return gcry_error (GPG_ERR_TOO_SHORT);
688
unsigned char *s = buffer;
698
for (i=0; i < n; i++)
700
unsigned int c = tmp[i];
702
*s++ = (c >> 4) < 10? '0'+(c>>4) : 'A'+(c>>4)-10 ;
704
*s++ = c < 10? '0'+c : 'A'+c-10 ;
707
*nwritten = s - buffer;
711
*nwritten = 2*n + extra + !!a->sign + 1;
717
return gcry_error (GPG_ERR_INV_ARG);
625
722
* Like gcry_mpi_print but this function allocates the buffer itself.
626
* The caller has to supply the address of a pointer. NWRITTEN may be
723
* The caller has to supply the address of a pointer. NWRITTEN may be
630
gcry_mpi_aprint( enum gcry_mpi_format format,
727
gcry_mpi_aprint (enum gcry_mpi_format format,
631
728
unsigned char **buffer, size_t *nwritten,
638
rc = gcry_mpi_print( format, NULL, 0, &n, a );
641
*buffer = mpi_is_secure(a) ? gcry_xmalloc_secure( n ) : gcry_xmalloc( n );
642
rc = gcry_mpi_print( format, *buffer, n, &n, a );
735
rc = gcry_mpi_print (format, NULL, 0, &n, a);
739
*buffer = mpi_is_secure(a) ? gcry_malloc_secure (n) : gcry_malloc (n);
741
return gpg_error_from_syserror ();
742
rc = gcry_mpi_print( format, *buffer, n, &n, a );