bignum.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * Big number math
  3. * Copyright (c) 2006, Jouni Malinen <j@w1.fi>
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. */
  8. #include "includes.h"
  9. #include "common.h"
  10. #include "bignum.h"
  11. #ifdef CONFIG_INTERNAL_LIBTOMMATH
  12. #include "libtommath.c"
  13. #else /* CONFIG_INTERNAL_LIBTOMMATH */
  14. #include <tommath.h>
  15. #endif /* CONFIG_INTERNAL_LIBTOMMATH */
  16. /*
  17. * The current version is just a wrapper for LibTomMath library, so
  18. * struct bignum is just typecast to mp_int.
  19. */
  20. /**
  21. * bignum_init - Allocate memory for bignum
  22. * Returns: Pointer to allocated bignum or %NULL on failure
  23. */
  24. struct bignum * bignum_init(void)
  25. {
  26. struct bignum *n = os_zalloc(sizeof(mp_int));
  27. if (n == NULL)
  28. return NULL;
  29. if (mp_init((mp_int *) n) != MP_OKAY) {
  30. os_free(n);
  31. n = NULL;
  32. }
  33. return n;
  34. }
  35. /**
  36. * bignum_deinit - Free bignum
  37. * @n: Bignum from bignum_init()
  38. */
  39. void bignum_deinit(struct bignum *n)
  40. {
  41. if (n) {
  42. mp_clear((mp_int *) n);
  43. os_free(n);
  44. }
  45. }
  46. /**
  47. * bignum_get_unsigned_bin - Get length of bignum as an unsigned binary buffer
  48. * @n: Bignum from bignum_init()
  49. * Returns: Length of n if written to a binary buffer
  50. */
  51. size_t bignum_get_unsigned_bin_len(struct bignum *n)
  52. {
  53. return mp_unsigned_bin_size((mp_int *) n);
  54. }
  55. /**
  56. * bignum_get_unsigned_bin - Set binary buffer to unsigned bignum
  57. * @n: Bignum from bignum_init()
  58. * @buf: Buffer for the binary number
  59. * @len: Length of the buffer, can be %NULL if buffer is known to be long
  60. * enough. Set to used buffer length on success if not %NULL.
  61. * Returns: 0 on success, -1 on failure
  62. */
  63. int bignum_get_unsigned_bin(const struct bignum *n, u8 *buf, size_t *len)
  64. {
  65. size_t need = mp_unsigned_bin_size((mp_int *) n);
  66. if (len && need > *len) {
  67. *len = need;
  68. return -1;
  69. }
  70. if (mp_to_unsigned_bin((mp_int *) n, buf) != MP_OKAY) {
  71. wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
  72. return -1;
  73. }
  74. if (len)
  75. *len = need;
  76. return 0;
  77. }
  78. /**
  79. * bignum_set_unsigned_bin - Set bignum based on unsigned binary buffer
  80. * @n: Bignum from bignum_init(); to be set to the given value
  81. * @buf: Buffer with unsigned binary value
  82. * @len: Length of buf in octets
  83. * Returns: 0 on success, -1 on failure
  84. */
  85. int bignum_set_unsigned_bin(struct bignum *n, const u8 *buf, size_t len)
  86. {
  87. if (mp_read_unsigned_bin((mp_int *) n, (u8 *) buf, len) != MP_OKAY) {
  88. wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
  89. return -1;
  90. }
  91. return 0;
  92. }
  93. /**
  94. * bignum_cmp - Signed comparison
  95. * @a: Bignum from bignum_init()
  96. * @b: Bignum from bignum_init()
  97. * Returns: 0 on success, -1 on failure
  98. */
  99. int bignum_cmp(const struct bignum *a, const struct bignum *b)
  100. {
  101. return mp_cmp((mp_int *) a, (mp_int *) b);
  102. }
  103. /**
  104. * bignum_cmd_d - Compare bignum to standard integer
  105. * @a: Bignum from bignum_init()
  106. * @b: Small integer
  107. * Returns: 0 on success, -1 on failure
  108. */
  109. int bignum_cmp_d(const struct bignum *a, unsigned long b)
  110. {
  111. return mp_cmp_d((mp_int *) a, b);
  112. }
  113. /**
  114. * bignum_add - c = a + b
  115. * @a: Bignum from bignum_init()
  116. * @b: Bignum from bignum_init()
  117. * @c: Bignum from bignum_init(); used to store the result of a + b
  118. * Returns: 0 on success, -1 on failure
  119. */
  120. int bignum_add(const struct bignum *a, const struct bignum *b,
  121. struct bignum *c)
  122. {
  123. if (mp_add((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) {
  124. wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
  125. return -1;
  126. }
  127. return 0;
  128. }
  129. /**
  130. * bignum_sub - c = a - b
  131. * @a: Bignum from bignum_init()
  132. * @b: Bignum from bignum_init()
  133. * @c: Bignum from bignum_init(); used to store the result of a - b
  134. * Returns: 0 on success, -1 on failure
  135. */
  136. int bignum_sub(const struct bignum *a, const struct bignum *b,
  137. struct bignum *c)
  138. {
  139. if (mp_sub((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) {
  140. wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
  141. return -1;
  142. }
  143. return 0;
  144. }
  145. /**
  146. * bignum_mul - c = a * b
  147. * @a: Bignum from bignum_init()
  148. * @b: Bignum from bignum_init()
  149. * @c: Bignum from bignum_init(); used to store the result of a * b
  150. * Returns: 0 on success, -1 on failure
  151. */
  152. int bignum_mul(const struct bignum *a, const struct bignum *b,
  153. struct bignum *c)
  154. {
  155. if (mp_mul((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) {
  156. wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
  157. return -1;
  158. }
  159. return 0;
  160. }
  161. /**
  162. * bignum_mulmod - d = a * b (mod c)
  163. * @a: Bignum from bignum_init()
  164. * @b: Bignum from bignum_init()
  165. * @c: Bignum from bignum_init(); modulus
  166. * @d: Bignum from bignum_init(); used to store the result of a * b (mod c)
  167. * Returns: 0 on success, -1 on failure
  168. */
  169. int bignum_mulmod(const struct bignum *a, const struct bignum *b,
  170. const struct bignum *c, struct bignum *d)
  171. {
  172. if (mp_mulmod((mp_int *) a, (mp_int *) b, (mp_int *) c, (mp_int *) d)
  173. != MP_OKAY) {
  174. wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
  175. return -1;
  176. }
  177. return 0;
  178. }
  179. /**
  180. * bignum_exptmod - Modular exponentiation: d = a^b (mod c)
  181. * @a: Bignum from bignum_init(); base
  182. * @b: Bignum from bignum_init(); exponent
  183. * @c: Bignum from bignum_init(); modulus
  184. * @d: Bignum from bignum_init(); used to store the result of a^b (mod c)
  185. * Returns: 0 on success, -1 on failure
  186. */
  187. int bignum_exptmod(const struct bignum *a, const struct bignum *b,
  188. const struct bignum *c, struct bignum *d)
  189. {
  190. if (mp_exptmod((mp_int *) a, (mp_int *) b, (mp_int *) c, (mp_int *) d)
  191. != MP_OKAY) {
  192. wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__);
  193. return -1;
  194. }
  195. return 0;
  196. }