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