ring-native 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (261) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/Gemfile +3 -0
  4. data/README.md +22 -0
  5. data/Rakefile +1 -0
  6. data/ext/ring/extconf.rb +29 -0
  7. data/lib/ring/native.rb +8 -0
  8. data/lib/ring/native/version.rb +5 -0
  9. data/ring-native.gemspec +25 -0
  10. data/vendor/ring/BUILDING.md +40 -0
  11. data/vendor/ring/Cargo.toml +43 -0
  12. data/vendor/ring/LICENSE +185 -0
  13. data/vendor/ring/Makefile +35 -0
  14. data/vendor/ring/PORTING.md +163 -0
  15. data/vendor/ring/README.md +113 -0
  16. data/vendor/ring/STYLE.md +197 -0
  17. data/vendor/ring/appveyor.yml +27 -0
  18. data/vendor/ring/build.rs +108 -0
  19. data/vendor/ring/crypto/aes/aes.c +1142 -0
  20. data/vendor/ring/crypto/aes/aes_test.Windows.vcxproj +25 -0
  21. data/vendor/ring/crypto/aes/aes_test.cc +93 -0
  22. data/vendor/ring/crypto/aes/asm/aes-586.pl +2368 -0
  23. data/vendor/ring/crypto/aes/asm/aes-armv4.pl +1249 -0
  24. data/vendor/ring/crypto/aes/asm/aes-x86_64.pl +2246 -0
  25. data/vendor/ring/crypto/aes/asm/aesni-x86.pl +1318 -0
  26. data/vendor/ring/crypto/aes/asm/aesni-x86_64.pl +2084 -0
  27. data/vendor/ring/crypto/aes/asm/aesv8-armx.pl +675 -0
  28. data/vendor/ring/crypto/aes/asm/bsaes-armv7.pl +1364 -0
  29. data/vendor/ring/crypto/aes/asm/bsaes-x86_64.pl +1565 -0
  30. data/vendor/ring/crypto/aes/asm/vpaes-x86.pl +841 -0
  31. data/vendor/ring/crypto/aes/asm/vpaes-x86_64.pl +1116 -0
  32. data/vendor/ring/crypto/aes/internal.h +87 -0
  33. data/vendor/ring/crypto/aes/mode_wrappers.c +61 -0
  34. data/vendor/ring/crypto/bn/add.c +394 -0
  35. data/vendor/ring/crypto/bn/asm/armv4-mont.pl +694 -0
  36. data/vendor/ring/crypto/bn/asm/armv8-mont.pl +1503 -0
  37. data/vendor/ring/crypto/bn/asm/bn-586.pl +774 -0
  38. data/vendor/ring/crypto/bn/asm/co-586.pl +287 -0
  39. data/vendor/ring/crypto/bn/asm/rsaz-avx2.pl +1882 -0
  40. data/vendor/ring/crypto/bn/asm/x86-mont.pl +592 -0
  41. data/vendor/ring/crypto/bn/asm/x86_64-gcc.c +599 -0
  42. data/vendor/ring/crypto/bn/asm/x86_64-mont.pl +1393 -0
  43. data/vendor/ring/crypto/bn/asm/x86_64-mont5.pl +3507 -0
  44. data/vendor/ring/crypto/bn/bn.c +352 -0
  45. data/vendor/ring/crypto/bn/bn_asn1.c +74 -0
  46. data/vendor/ring/crypto/bn/bn_test.Windows.vcxproj +25 -0
  47. data/vendor/ring/crypto/bn/bn_test.cc +1696 -0
  48. data/vendor/ring/crypto/bn/cmp.c +200 -0
  49. data/vendor/ring/crypto/bn/convert.c +433 -0
  50. data/vendor/ring/crypto/bn/ctx.c +311 -0
  51. data/vendor/ring/crypto/bn/div.c +594 -0
  52. data/vendor/ring/crypto/bn/exponentiation.c +1335 -0
  53. data/vendor/ring/crypto/bn/gcd.c +711 -0
  54. data/vendor/ring/crypto/bn/generic.c +1019 -0
  55. data/vendor/ring/crypto/bn/internal.h +316 -0
  56. data/vendor/ring/crypto/bn/montgomery.c +516 -0
  57. data/vendor/ring/crypto/bn/mul.c +888 -0
  58. data/vendor/ring/crypto/bn/prime.c +829 -0
  59. data/vendor/ring/crypto/bn/random.c +334 -0
  60. data/vendor/ring/crypto/bn/rsaz_exp.c +262 -0
  61. data/vendor/ring/crypto/bn/rsaz_exp.h +53 -0
  62. data/vendor/ring/crypto/bn/shift.c +276 -0
  63. data/vendor/ring/crypto/bytestring/bytestring_test.Windows.vcxproj +25 -0
  64. data/vendor/ring/crypto/bytestring/bytestring_test.cc +421 -0
  65. data/vendor/ring/crypto/bytestring/cbb.c +399 -0
  66. data/vendor/ring/crypto/bytestring/cbs.c +227 -0
  67. data/vendor/ring/crypto/bytestring/internal.h +46 -0
  68. data/vendor/ring/crypto/chacha/chacha_generic.c +140 -0
  69. data/vendor/ring/crypto/chacha/chacha_vec.c +323 -0
  70. data/vendor/ring/crypto/chacha/chacha_vec_arm.S +1447 -0
  71. data/vendor/ring/crypto/chacha/chacha_vec_arm_generate.go +153 -0
  72. data/vendor/ring/crypto/cipher/cipher_test.Windows.vcxproj +25 -0
  73. data/vendor/ring/crypto/cipher/e_aes.c +390 -0
  74. data/vendor/ring/crypto/cipher/e_chacha20poly1305.c +208 -0
  75. data/vendor/ring/crypto/cipher/internal.h +173 -0
  76. data/vendor/ring/crypto/cipher/test/aes_128_gcm_tests.txt +543 -0
  77. data/vendor/ring/crypto/cipher/test/aes_128_key_wrap_tests.txt +9 -0
  78. data/vendor/ring/crypto/cipher/test/aes_256_gcm_tests.txt +475 -0
  79. data/vendor/ring/crypto/cipher/test/aes_256_key_wrap_tests.txt +23 -0
  80. data/vendor/ring/crypto/cipher/test/chacha20_poly1305_old_tests.txt +422 -0
  81. data/vendor/ring/crypto/cipher/test/chacha20_poly1305_tests.txt +484 -0
  82. data/vendor/ring/crypto/cipher/test/cipher_test.txt +100 -0
  83. data/vendor/ring/crypto/constant_time_test.Windows.vcxproj +25 -0
  84. data/vendor/ring/crypto/constant_time_test.c +304 -0
  85. data/vendor/ring/crypto/cpu-arm-asm.S +32 -0
  86. data/vendor/ring/crypto/cpu-arm.c +199 -0
  87. data/vendor/ring/crypto/cpu-intel.c +261 -0
  88. data/vendor/ring/crypto/crypto.c +151 -0
  89. data/vendor/ring/crypto/curve25519/asm/x25519-arm.S +2118 -0
  90. data/vendor/ring/crypto/curve25519/curve25519.c +4888 -0
  91. data/vendor/ring/crypto/curve25519/x25519_test.cc +128 -0
  92. data/vendor/ring/crypto/digest/md32_common.h +181 -0
  93. data/vendor/ring/crypto/ec/asm/p256-x86_64-asm.pl +2725 -0
  94. data/vendor/ring/crypto/ec/ec.c +193 -0
  95. data/vendor/ring/crypto/ec/ec_curves.c +61 -0
  96. data/vendor/ring/crypto/ec/ec_key.c +228 -0
  97. data/vendor/ring/crypto/ec/ec_montgomery.c +114 -0
  98. data/vendor/ring/crypto/ec/example_mul.Windows.vcxproj +25 -0
  99. data/vendor/ring/crypto/ec/internal.h +243 -0
  100. data/vendor/ring/crypto/ec/oct.c +253 -0
  101. data/vendor/ring/crypto/ec/p256-64.c +1794 -0
  102. data/vendor/ring/crypto/ec/p256-x86_64-table.h +9548 -0
  103. data/vendor/ring/crypto/ec/p256-x86_64.c +509 -0
  104. data/vendor/ring/crypto/ec/simple.c +1007 -0
  105. data/vendor/ring/crypto/ec/util-64.c +183 -0
  106. data/vendor/ring/crypto/ec/wnaf.c +508 -0
  107. data/vendor/ring/crypto/ecdh/ecdh.c +155 -0
  108. data/vendor/ring/crypto/ecdsa/ecdsa.c +304 -0
  109. data/vendor/ring/crypto/ecdsa/ecdsa_asn1.c +193 -0
  110. data/vendor/ring/crypto/ecdsa/ecdsa_test.Windows.vcxproj +25 -0
  111. data/vendor/ring/crypto/ecdsa/ecdsa_test.cc +327 -0
  112. data/vendor/ring/crypto/header_removed.h +17 -0
  113. data/vendor/ring/crypto/internal.h +495 -0
  114. data/vendor/ring/crypto/libring.Windows.vcxproj +101 -0
  115. data/vendor/ring/crypto/mem.c +98 -0
  116. data/vendor/ring/crypto/modes/asm/aesni-gcm-x86_64.pl +1045 -0
  117. data/vendor/ring/crypto/modes/asm/ghash-armv4.pl +517 -0
  118. data/vendor/ring/crypto/modes/asm/ghash-x86.pl +1393 -0
  119. data/vendor/ring/crypto/modes/asm/ghash-x86_64.pl +1741 -0
  120. data/vendor/ring/crypto/modes/asm/ghashv8-armx.pl +422 -0
  121. data/vendor/ring/crypto/modes/ctr.c +226 -0
  122. data/vendor/ring/crypto/modes/gcm.c +1206 -0
  123. data/vendor/ring/crypto/modes/gcm_test.Windows.vcxproj +25 -0
  124. data/vendor/ring/crypto/modes/gcm_test.c +348 -0
  125. data/vendor/ring/crypto/modes/internal.h +299 -0
  126. data/vendor/ring/crypto/perlasm/arm-xlate.pl +170 -0
  127. data/vendor/ring/crypto/perlasm/readme +100 -0
  128. data/vendor/ring/crypto/perlasm/x86_64-xlate.pl +1164 -0
  129. data/vendor/ring/crypto/perlasm/x86asm.pl +292 -0
  130. data/vendor/ring/crypto/perlasm/x86gas.pl +263 -0
  131. data/vendor/ring/crypto/perlasm/x86masm.pl +200 -0
  132. data/vendor/ring/crypto/perlasm/x86nasm.pl +187 -0
  133. data/vendor/ring/crypto/poly1305/poly1305.c +331 -0
  134. data/vendor/ring/crypto/poly1305/poly1305_arm.c +301 -0
  135. data/vendor/ring/crypto/poly1305/poly1305_arm_asm.S +2015 -0
  136. data/vendor/ring/crypto/poly1305/poly1305_test.Windows.vcxproj +25 -0
  137. data/vendor/ring/crypto/poly1305/poly1305_test.cc +80 -0
  138. data/vendor/ring/crypto/poly1305/poly1305_test.txt +52 -0
  139. data/vendor/ring/crypto/poly1305/poly1305_vec.c +892 -0
  140. data/vendor/ring/crypto/rand/asm/rdrand-x86_64.pl +75 -0
  141. data/vendor/ring/crypto/rand/internal.h +32 -0
  142. data/vendor/ring/crypto/rand/rand.c +189 -0
  143. data/vendor/ring/crypto/rand/urandom.c +219 -0
  144. data/vendor/ring/crypto/rand/windows.c +56 -0
  145. data/vendor/ring/crypto/refcount_c11.c +66 -0
  146. data/vendor/ring/crypto/refcount_lock.c +53 -0
  147. data/vendor/ring/crypto/refcount_test.Windows.vcxproj +25 -0
  148. data/vendor/ring/crypto/refcount_test.c +58 -0
  149. data/vendor/ring/crypto/rsa/blinding.c +462 -0
  150. data/vendor/ring/crypto/rsa/internal.h +108 -0
  151. data/vendor/ring/crypto/rsa/padding.c +300 -0
  152. data/vendor/ring/crypto/rsa/rsa.c +450 -0
  153. data/vendor/ring/crypto/rsa/rsa_asn1.c +261 -0
  154. data/vendor/ring/crypto/rsa/rsa_impl.c +944 -0
  155. data/vendor/ring/crypto/rsa/rsa_test.Windows.vcxproj +25 -0
  156. data/vendor/ring/crypto/rsa/rsa_test.cc +437 -0
  157. data/vendor/ring/crypto/sha/asm/sha-armv8.pl +436 -0
  158. data/vendor/ring/crypto/sha/asm/sha-x86_64.pl +2390 -0
  159. data/vendor/ring/crypto/sha/asm/sha256-586.pl +1275 -0
  160. data/vendor/ring/crypto/sha/asm/sha256-armv4.pl +735 -0
  161. data/vendor/ring/crypto/sha/asm/sha256-armv8.pl +14 -0
  162. data/vendor/ring/crypto/sha/asm/sha256-x86_64.pl +14 -0
  163. data/vendor/ring/crypto/sha/asm/sha512-586.pl +911 -0
  164. data/vendor/ring/crypto/sha/asm/sha512-armv4.pl +666 -0
  165. data/vendor/ring/crypto/sha/asm/sha512-armv8.pl +14 -0
  166. data/vendor/ring/crypto/sha/asm/sha512-x86_64.pl +14 -0
  167. data/vendor/ring/crypto/sha/sha1.c +271 -0
  168. data/vendor/ring/crypto/sha/sha256.c +204 -0
  169. data/vendor/ring/crypto/sha/sha512.c +355 -0
  170. data/vendor/ring/crypto/test/file_test.cc +326 -0
  171. data/vendor/ring/crypto/test/file_test.h +181 -0
  172. data/vendor/ring/crypto/test/malloc.cc +150 -0
  173. data/vendor/ring/crypto/test/scoped_types.h +95 -0
  174. data/vendor/ring/crypto/test/test.Windows.vcxproj +35 -0
  175. data/vendor/ring/crypto/test/test_util.cc +46 -0
  176. data/vendor/ring/crypto/test/test_util.h +41 -0
  177. data/vendor/ring/crypto/thread_none.c +55 -0
  178. data/vendor/ring/crypto/thread_pthread.c +165 -0
  179. data/vendor/ring/crypto/thread_test.Windows.vcxproj +25 -0
  180. data/vendor/ring/crypto/thread_test.c +200 -0
  181. data/vendor/ring/crypto/thread_win.c +282 -0
  182. data/vendor/ring/examples/checkdigest.rs +103 -0
  183. data/vendor/ring/include/openssl/aes.h +121 -0
  184. data/vendor/ring/include/openssl/arm_arch.h +129 -0
  185. data/vendor/ring/include/openssl/base.h +156 -0
  186. data/vendor/ring/include/openssl/bn.h +794 -0
  187. data/vendor/ring/include/openssl/buffer.h +18 -0
  188. data/vendor/ring/include/openssl/bytestring.h +235 -0
  189. data/vendor/ring/include/openssl/chacha.h +37 -0
  190. data/vendor/ring/include/openssl/cmac.h +76 -0
  191. data/vendor/ring/include/openssl/cpu.h +184 -0
  192. data/vendor/ring/include/openssl/crypto.h +43 -0
  193. data/vendor/ring/include/openssl/curve25519.h +88 -0
  194. data/vendor/ring/include/openssl/ec.h +225 -0
  195. data/vendor/ring/include/openssl/ec_key.h +129 -0
  196. data/vendor/ring/include/openssl/ecdh.h +110 -0
  197. data/vendor/ring/include/openssl/ecdsa.h +156 -0
  198. data/vendor/ring/include/openssl/err.h +201 -0
  199. data/vendor/ring/include/openssl/mem.h +101 -0
  200. data/vendor/ring/include/openssl/obj_mac.h +71 -0
  201. data/vendor/ring/include/openssl/opensslfeatures.h +68 -0
  202. data/vendor/ring/include/openssl/opensslv.h +18 -0
  203. data/vendor/ring/include/openssl/ossl_typ.h +18 -0
  204. data/vendor/ring/include/openssl/poly1305.h +51 -0
  205. data/vendor/ring/include/openssl/rand.h +70 -0
  206. data/vendor/ring/include/openssl/rsa.h +399 -0
  207. data/vendor/ring/include/openssl/thread.h +133 -0
  208. data/vendor/ring/include/openssl/type_check.h +71 -0
  209. data/vendor/ring/mk/Common.props +63 -0
  210. data/vendor/ring/mk/Windows.props +42 -0
  211. data/vendor/ring/mk/WindowsTest.props +18 -0
  212. data/vendor/ring/mk/appveyor.bat +62 -0
  213. data/vendor/ring/mk/bottom_of_makefile.mk +54 -0
  214. data/vendor/ring/mk/ring.mk +266 -0
  215. data/vendor/ring/mk/top_of_makefile.mk +214 -0
  216. data/vendor/ring/mk/travis.sh +40 -0
  217. data/vendor/ring/mk/update-travis-yml.py +229 -0
  218. data/vendor/ring/ring.sln +153 -0
  219. data/vendor/ring/src/aead.rs +682 -0
  220. data/vendor/ring/src/agreement.rs +248 -0
  221. data/vendor/ring/src/c.rs +129 -0
  222. data/vendor/ring/src/constant_time.rs +37 -0
  223. data/vendor/ring/src/der.rs +96 -0
  224. data/vendor/ring/src/digest.rs +690 -0
  225. data/vendor/ring/src/digest_tests.txt +57 -0
  226. data/vendor/ring/src/ecc.rs +28 -0
  227. data/vendor/ring/src/ecc_build.rs +279 -0
  228. data/vendor/ring/src/ecc_curves.rs +117 -0
  229. data/vendor/ring/src/ed25519_tests.txt +2579 -0
  230. data/vendor/ring/src/exe_tests.rs +46 -0
  231. data/vendor/ring/src/ffi.rs +29 -0
  232. data/vendor/ring/src/file_test.rs +187 -0
  233. data/vendor/ring/src/hkdf.rs +153 -0
  234. data/vendor/ring/src/hkdf_tests.txt +59 -0
  235. data/vendor/ring/src/hmac.rs +414 -0
  236. data/vendor/ring/src/hmac_tests.txt +97 -0
  237. data/vendor/ring/src/input.rs +312 -0
  238. data/vendor/ring/src/lib.rs +41 -0
  239. data/vendor/ring/src/pbkdf2.rs +265 -0
  240. data/vendor/ring/src/pbkdf2_tests.txt +113 -0
  241. data/vendor/ring/src/polyfill.rs +57 -0
  242. data/vendor/ring/src/rand.rs +28 -0
  243. data/vendor/ring/src/signature.rs +314 -0
  244. data/vendor/ring/third-party/NIST/README.md +9 -0
  245. data/vendor/ring/third-party/NIST/SHAVS/SHA1LongMsg.rsp +263 -0
  246. data/vendor/ring/third-party/NIST/SHAVS/SHA1Monte.rsp +309 -0
  247. data/vendor/ring/third-party/NIST/SHAVS/SHA1ShortMsg.rsp +267 -0
  248. data/vendor/ring/third-party/NIST/SHAVS/SHA224LongMsg.rsp +263 -0
  249. data/vendor/ring/third-party/NIST/SHAVS/SHA224Monte.rsp +309 -0
  250. data/vendor/ring/third-party/NIST/SHAVS/SHA224ShortMsg.rsp +267 -0
  251. data/vendor/ring/third-party/NIST/SHAVS/SHA256LongMsg.rsp +263 -0
  252. data/vendor/ring/third-party/NIST/SHAVS/SHA256Monte.rsp +309 -0
  253. data/vendor/ring/third-party/NIST/SHAVS/SHA256ShortMsg.rsp +267 -0
  254. data/vendor/ring/third-party/NIST/SHAVS/SHA384LongMsg.rsp +519 -0
  255. data/vendor/ring/third-party/NIST/SHAVS/SHA384Monte.rsp +309 -0
  256. data/vendor/ring/third-party/NIST/SHAVS/SHA384ShortMsg.rsp +523 -0
  257. data/vendor/ring/third-party/NIST/SHAVS/SHA512LongMsg.rsp +519 -0
  258. data/vendor/ring/third-party/NIST/SHAVS/SHA512Monte.rsp +309 -0
  259. data/vendor/ring/third-party/NIST/SHAVS/SHA512ShortMsg.rsp +523 -0
  260. data/vendor/ring/third-party/NIST/sha256sums.txt +1 -0
  261. metadata +333 -0
@@ -0,0 +1,1335 @@
1
+ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2
+ * All rights reserved.
3
+ *
4
+ * This package is an SSL implementation written
5
+ * by Eric Young (eay@cryptsoft.com).
6
+ * The implementation was written so as to conform with Netscapes SSL.
7
+ *
8
+ * This library is free for commercial and non-commercial use as long as
9
+ * the following conditions are aheared to. The following conditions
10
+ * apply to all code found in this distribution, be it the RC4, RSA,
11
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12
+ * included with this distribution is covered by the same copyright terms
13
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14
+ *
15
+ * Copyright remains Eric Young's, and as such any Copyright notices in
16
+ * the code are not to be removed.
17
+ * If this package is used in a product, Eric Young should be given attribution
18
+ * as the author of the parts of the library used.
19
+ * This can be in the form of a textual message at program startup or
20
+ * in documentation (online or textual) provided with the package.
21
+ *
22
+ * Redistribution and use in source and binary forms, with or without
23
+ * modification, are permitted provided that the following conditions
24
+ * are met:
25
+ * 1. Redistributions of source code must retain the copyright
26
+ * notice, this list of conditions and the following disclaimer.
27
+ * 2. Redistributions in binary form must reproduce the above copyright
28
+ * notice, this list of conditions and the following disclaimer in the
29
+ * documentation and/or other materials provided with the distribution.
30
+ * 3. All advertising materials mentioning features or use of this software
31
+ * must display the following acknowledgement:
32
+ * "This product includes cryptographic software written by
33
+ * Eric Young (eay@cryptsoft.com)"
34
+ * The word 'cryptographic' can be left out if the rouines from the library
35
+ * being used are not cryptographic related :-).
36
+ * 4. If you include any Windows specific code (or a derivative thereof) from
37
+ * the apps directory (application code) you must include an acknowledgement:
38
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39
+ *
40
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50
+ * SUCH DAMAGE.
51
+ *
52
+ * The licence and distribution terms for any publically available version or
53
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
54
+ * copied and put under another distribution licence
55
+ * [including the GNU Public Licence.]
56
+ */
57
+ /* ====================================================================
58
+ * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
59
+ *
60
+ * Redistribution and use in source and binary forms, with or without
61
+ * modification, are permitted provided that the following conditions
62
+ * are met:
63
+ *
64
+ * 1. Redistributions of source code must retain the above copyright
65
+ * notice, this list of conditions and the following disclaimer.
66
+ *
67
+ * 2. Redistributions in binary form must reproduce the above copyright
68
+ * notice, this list of conditions and the following disclaimer in
69
+ * the documentation and/or other materials provided with the
70
+ * distribution.
71
+ *
72
+ * 3. All advertising materials mentioning features or use of this
73
+ * software must display the following acknowledgment:
74
+ * "This product includes software developed by the OpenSSL Project
75
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76
+ *
77
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78
+ * endorse or promote products derived from this software without
79
+ * prior written permission. For written permission, please contact
80
+ * openssl-core@openssl.org.
81
+ *
82
+ * 5. Products derived from this software may not be called "OpenSSL"
83
+ * nor may "OpenSSL" appear in their names without prior written
84
+ * permission of the OpenSSL Project.
85
+ *
86
+ * 6. Redistributions of any form whatsoever must retain the following
87
+ * acknowledgment:
88
+ * "This product includes software developed by the OpenSSL Project
89
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90
+ *
91
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
95
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
103
+ * ====================================================================
104
+ *
105
+ * This product includes cryptographic software written by Eric Young
106
+ * (eay@cryptsoft.com). This product includes software written by Tim
107
+ * Hudson (tjh@cryptsoft.com). */
108
+
109
+ #include <openssl/bn.h>
110
+
111
+ #include <assert.h>
112
+ #include <string.h>
113
+
114
+ #include <openssl/cpu.h>
115
+ #include <openssl/err.h>
116
+ #include <openssl/mem.h>
117
+
118
+ #include "internal.h"
119
+
120
+
121
+ #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64)
122
+ #define OPENSSL_BN_ASM_MONT5
123
+ #define RSAZ_ENABLED
124
+
125
+ #include "rsaz_exp.h"
126
+
127
+ void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap, const void *table,
128
+ const BN_ULONG *np, const BN_ULONG *n0, int num,
129
+ int power);
130
+ void bn_scatter5(const BN_ULONG *inp, size_t num, void *table, size_t power);
131
+ void bn_gather5(BN_ULONG *out, size_t num, void *table, size_t power);
132
+ void bn_power5(BN_ULONG *rp, const BN_ULONG *ap, const void *table,
133
+ const BN_ULONG *np, const BN_ULONG *n0, int num, int power);
134
+ int bn_from_montgomery(BN_ULONG *rp, const BN_ULONG *ap,
135
+ const BN_ULONG *not_used, const BN_ULONG *np,
136
+ const BN_ULONG *n0, int num);
137
+ #endif
138
+
139
+ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
140
+ int i, bits, ret = 0;
141
+ BIGNUM *v, *rr;
142
+
143
+ if ((p->flags & BN_FLG_CONSTTIME) != 0) {
144
+ /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
145
+ OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
146
+ return 0;
147
+ }
148
+
149
+ BN_CTX_start(ctx);
150
+ if (r == a || r == p) {
151
+ rr = BN_CTX_get(ctx);
152
+ } else {
153
+ rr = r;
154
+ }
155
+
156
+ v = BN_CTX_get(ctx);
157
+ if (rr == NULL || v == NULL) {
158
+ goto err;
159
+ }
160
+
161
+ if (BN_copy(v, a) == NULL) {
162
+ goto err;
163
+ }
164
+ bits = BN_num_bits(p);
165
+
166
+ if (BN_is_odd(p)) {
167
+ if (BN_copy(rr, a) == NULL) {
168
+ goto err;
169
+ }
170
+ } else {
171
+ if (!BN_one(rr)) {
172
+ goto err;
173
+ }
174
+ }
175
+
176
+ for (i = 1; i < bits; i++) {
177
+ if (!BN_sqr(v, v, ctx)) {
178
+ goto err;
179
+ }
180
+ if (BN_is_bit_set(p, i)) {
181
+ if (!BN_mul(rr, rr, v, ctx)) {
182
+ goto err;
183
+ }
184
+ }
185
+ }
186
+
187
+ if (r != rr && !BN_copy(r, rr)) {
188
+ goto err;
189
+ }
190
+ ret = 1;
191
+
192
+ err:
193
+ BN_CTX_end(ctx);
194
+ return ret;
195
+ }
196
+
197
+ /* maximum precomputation table size for *variable* sliding windows */
198
+ #define TABLE_SIZE 32
199
+
200
+ typedef struct bn_recp_ctx_st {
201
+ BIGNUM N; /* the divisor */
202
+ BIGNUM Nr; /* the reciprocal */
203
+ int num_bits;
204
+ int shift;
205
+ int flags;
206
+ } BN_RECP_CTX;
207
+
208
+ static void BN_RECP_CTX_init(BN_RECP_CTX *recp) {
209
+ BN_init(&recp->N);
210
+ BN_init(&recp->Nr);
211
+ recp->num_bits = 0;
212
+ recp->flags = 0;
213
+ }
214
+
215
+ static void BN_RECP_CTX_free(BN_RECP_CTX *recp) {
216
+ if (recp == NULL) {
217
+ return;
218
+ }
219
+
220
+ BN_free(&recp->N);
221
+ BN_free(&recp->Nr);
222
+ }
223
+
224
+ static int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx) {
225
+ if (!BN_copy(&(recp->N), d)) {
226
+ return 0;
227
+ }
228
+ BN_zero(&recp->Nr);
229
+ recp->num_bits = BN_num_bits(d);
230
+ recp->shift = 0;
231
+
232
+ return 1;
233
+ }
234
+
235
+ /* len is the expected size of the result We actually calculate with an extra
236
+ * word of precision, so we can do faster division if the remainder is not
237
+ * required.
238
+ * r := 2^len / m */
239
+ static int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx) {
240
+ int ret = -1;
241
+ BIGNUM *t;
242
+
243
+ BN_CTX_start(ctx);
244
+ t = BN_CTX_get(ctx);
245
+ if (t == NULL) {
246
+ goto err;
247
+ }
248
+
249
+ if (!BN_set_bit(t, len)) {
250
+ goto err;
251
+ }
252
+
253
+ if (!BN_div(r, NULL, t, m, ctx)) {
254
+ goto err;
255
+ }
256
+
257
+ ret = len;
258
+
259
+ err:
260
+ BN_CTX_end(ctx);
261
+ return ret;
262
+ }
263
+
264
+ static int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
265
+ BN_RECP_CTX *recp, BN_CTX *ctx) {
266
+ int i, j, ret = 0;
267
+ BIGNUM *a, *b, *d, *r;
268
+
269
+ BN_CTX_start(ctx);
270
+ a = BN_CTX_get(ctx);
271
+ b = BN_CTX_get(ctx);
272
+ if (dv != NULL) {
273
+ d = dv;
274
+ } else {
275
+ d = BN_CTX_get(ctx);
276
+ }
277
+
278
+ if (rem != NULL) {
279
+ r = rem;
280
+ } else {
281
+ r = BN_CTX_get(ctx);
282
+ }
283
+
284
+ if (a == NULL || b == NULL || d == NULL || r == NULL) {
285
+ goto err;
286
+ }
287
+
288
+ if (BN_ucmp(m, &recp->N) < 0) {
289
+ BN_zero(d);
290
+ if (!BN_copy(r, m)) {
291
+ goto err;
292
+ }
293
+ BN_CTX_end(ctx);
294
+ return 1;
295
+ }
296
+
297
+ /* We want the remainder
298
+ * Given input of ABCDEF / ab
299
+ * we need multiply ABCDEF by 3 digests of the reciprocal of ab */
300
+
301
+ /* i := max(BN_num_bits(m), 2*BN_num_bits(N)) */
302
+ i = BN_num_bits(m);
303
+ j = recp->num_bits << 1;
304
+ if (j > i) {
305
+ i = j;
306
+ }
307
+
308
+ /* Nr := round(2^i / N) */
309
+ if (i != recp->shift) {
310
+ recp->shift =
311
+ BN_reciprocal(&(recp->Nr), &(recp->N), i,
312
+ ctx); /* BN_reciprocal returns i, or -1 for an error */
313
+ }
314
+
315
+ if (recp->shift == -1) {
316
+ goto err;
317
+ }
318
+
319
+ /* d := |round(round(m / 2^BN_num_bits(N)) * recp->Nr / 2^(i -
320
+ * BN_num_bits(N)))|
321
+ * = |round(round(m / 2^BN_num_bits(N)) * round(2^i / N) / 2^(i -
322
+ * BN_num_bits(N)))|
323
+ * <= |(m / 2^BN_num_bits(N)) * (2^i / N) * (2^BN_num_bits(N) / 2^i)|
324
+ * = |m/N| */
325
+ if (!BN_rshift(a, m, recp->num_bits)) {
326
+ goto err;
327
+ }
328
+ if (!BN_mul(b, a, &(recp->Nr), ctx)) {
329
+ goto err;
330
+ }
331
+ if (!BN_rshift(d, b, i - recp->num_bits)) {
332
+ goto err;
333
+ }
334
+ d->neg = 0;
335
+
336
+ if (!BN_mul(b, &(recp->N), d, ctx)) {
337
+ goto err;
338
+ }
339
+ if (!BN_usub(r, m, b)) {
340
+ goto err;
341
+ }
342
+ r->neg = 0;
343
+
344
+ j = 0;
345
+ while (BN_ucmp(r, &(recp->N)) >= 0) {
346
+ if (j++ > 2) {
347
+ OPENSSL_PUT_ERROR(BN, BN_R_BAD_RECIPROCAL);
348
+ goto err;
349
+ }
350
+ if (!BN_usub(r, r, &(recp->N))) {
351
+ goto err;
352
+ }
353
+ if (!BN_add_word(d, 1)) {
354
+ goto err;
355
+ }
356
+ }
357
+
358
+ r->neg = BN_is_zero(r) ? 0 : m->neg;
359
+ d->neg = m->neg ^ recp->N.neg;
360
+ ret = 1;
361
+
362
+ err:
363
+ BN_CTX_end(ctx);
364
+ return ret;
365
+ }
366
+
367
+ static int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
368
+ BN_RECP_CTX *recp, BN_CTX *ctx) {
369
+ int ret = 0;
370
+ BIGNUM *a;
371
+ const BIGNUM *ca;
372
+
373
+ BN_CTX_start(ctx);
374
+ a = BN_CTX_get(ctx);
375
+ if (a == NULL) {
376
+ goto err;
377
+ }
378
+
379
+ if (y != NULL) {
380
+ if (x == y) {
381
+ if (!BN_sqr(a, x, ctx)) {
382
+ goto err;
383
+ }
384
+ } else {
385
+ if (!BN_mul(a, x, y, ctx)) {
386
+ goto err;
387
+ }
388
+ }
389
+ ca = a;
390
+ } else {
391
+ ca = x; /* Just do the mod */
392
+ }
393
+
394
+ ret = BN_div_recp(NULL, r, ca, recp, ctx);
395
+
396
+ err:
397
+ BN_CTX_end(ctx);
398
+ return ret;
399
+ }
400
+
401
+ /* BN_window_bits_for_exponent_size -- macro for sliding window mod_exp
402
+ * functions
403
+ *
404
+ * For window size 'w' (w >= 2) and a random 'b' bits exponent, the number of
405
+ * multiplications is a constant plus on average
406
+ *
407
+ * 2^(w-1) + (b-w)/(w+1);
408
+ *
409
+ * here 2^(w-1) is for precomputing the table (we actually need entries only
410
+ * for windows that have the lowest bit set), and (b-w)/(w+1) is an
411
+ * approximation for the expected number of w-bit windows, not counting the
412
+ * first one.
413
+ *
414
+ * Thus we should use
415
+ *
416
+ * w >= 6 if b > 671
417
+ * w = 5 if 671 > b > 239
418
+ * w = 4 if 239 > b > 79
419
+ * w = 3 if 79 > b > 23
420
+ * w <= 2 if 23 > b
421
+ *
422
+ * (with draws in between). Very small exponents are often selected
423
+ * with low Hamming weight, so we use w = 1 for b <= 23. */
424
+ #define BN_window_bits_for_exponent_size(b) \
425
+ ((b) > 671 ? 6 : \
426
+ (b) > 239 ? 5 : \
427
+ (b) > 79 ? 4 : \
428
+ (b) > 23 ? 3 : 1)
429
+
430
+ static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
431
+ const BIGNUM *m, BN_CTX *ctx) {
432
+ int i, j, bits, ret = 0, wstart, window;
433
+ int start = 1;
434
+ BIGNUM *aa;
435
+ /* Table of variables obtained from 'ctx' */
436
+ BIGNUM *val[TABLE_SIZE];
437
+ BN_RECP_CTX recp;
438
+
439
+ if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
440
+ /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
441
+ OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
442
+ return 0;
443
+ }
444
+
445
+ bits = BN_num_bits(p);
446
+
447
+ if (bits == 0) {
448
+ ret = BN_one(r);
449
+ return ret;
450
+ }
451
+
452
+ BN_CTX_start(ctx);
453
+ aa = BN_CTX_get(ctx);
454
+ val[0] = BN_CTX_get(ctx);
455
+ if (!aa || !val[0]) {
456
+ goto err;
457
+ }
458
+
459
+ BN_RECP_CTX_init(&recp);
460
+ if (m->neg) {
461
+ /* ignore sign of 'm' */
462
+ if (!BN_copy(aa, m)) {
463
+ goto err;
464
+ }
465
+ aa->neg = 0;
466
+ if (BN_RECP_CTX_set(&recp, aa, ctx) <= 0) {
467
+ goto err;
468
+ }
469
+ } else {
470
+ if (BN_RECP_CTX_set(&recp, m, ctx) <= 0) {
471
+ goto err;
472
+ }
473
+ }
474
+
475
+ if (!BN_nnmod(val[0], a, m, ctx)) {
476
+ goto err; /* 1 */
477
+ }
478
+ if (BN_is_zero(val[0])) {
479
+ BN_zero(r);
480
+ ret = 1;
481
+ goto err;
482
+ }
483
+
484
+ window = BN_window_bits_for_exponent_size(bits);
485
+ if (window > 1) {
486
+ if (!BN_mod_mul_reciprocal(aa, val[0], val[0], &recp, ctx)) {
487
+ goto err; /* 2 */
488
+ }
489
+ j = 1 << (window - 1);
490
+ for (i = 1; i < j; i++) {
491
+ if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
492
+ !BN_mod_mul_reciprocal(val[i], val[i - 1], aa, &recp, ctx)) {
493
+ goto err;
494
+ }
495
+ }
496
+ }
497
+
498
+ start = 1; /* This is used to avoid multiplication etc
499
+ * when there is only the value '1' in the
500
+ * buffer. */
501
+ wstart = bits - 1; /* The top bit of the window */
502
+
503
+ if (!BN_one(r)) {
504
+ goto err;
505
+ }
506
+
507
+ for (;;) {
508
+ int wvalue; /* The 'value' of the window */
509
+ int wend; /* The bottom bit of the window */
510
+
511
+ if (BN_is_bit_set(p, wstart) == 0) {
512
+ if (!start) {
513
+ if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx)) {
514
+ goto err;
515
+ }
516
+ }
517
+ if (wstart == 0) {
518
+ break;
519
+ }
520
+ wstart--;
521
+ continue;
522
+ }
523
+
524
+ /* We now have wstart on a 'set' bit, we now need to work out
525
+ * how bit a window to do. To do this we need to scan
526
+ * forward until the last set bit before the end of the
527
+ * window */
528
+ wvalue = 1;
529
+ wend = 0;
530
+ for (i = 1; i < window; i++) {
531
+ if (wstart - i < 0) {
532
+ break;
533
+ }
534
+ if (BN_is_bit_set(p, wstart - i)) {
535
+ wvalue <<= (i - wend);
536
+ wvalue |= 1;
537
+ wend = i;
538
+ }
539
+ }
540
+
541
+ /* wend is the size of the current window */
542
+ j = wend + 1;
543
+ /* add the 'bytes above' */
544
+ if (!start) {
545
+ for (i = 0; i < j; i++) {
546
+ if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx)) {
547
+ goto err;
548
+ }
549
+ }
550
+ }
551
+
552
+ /* wvalue will be an odd number < 2^window */
553
+ if (!BN_mod_mul_reciprocal(r, r, val[wvalue >> 1], &recp, ctx)) {
554
+ goto err;
555
+ }
556
+
557
+ /* move the 'window' down further */
558
+ wstart -= wend + 1;
559
+ start = 0;
560
+ if (wstart < 0) {
561
+ break;
562
+ }
563
+ }
564
+ ret = 1;
565
+
566
+ err:
567
+ BN_CTX_end(ctx);
568
+ BN_RECP_CTX_free(&recp);
569
+ return ret;
570
+ }
571
+
572
+ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
573
+ BN_CTX *ctx) {
574
+ /* For even modulus m = 2^k*m_odd, it might make sense to compute
575
+ * a^p mod m_odd and a^p mod 2^k separately (with Montgomery
576
+ * exponentiation for the odd part), using appropriate exponent
577
+ * reductions, and combine the results using the CRT.
578
+ *
579
+ * For now, we use Montgomery only if the modulus is odd; otherwise,
580
+ * exponentiation using the reciprocal-based quick remaindering
581
+ * algorithm is used.
582
+ *
583
+ * (Timing obtained with expspeed.c [computations a^p mod m
584
+ * where a, p, m are of the same length: 256, 512, 1024, 2048,
585
+ * 4096, 8192 bits], compared to the running time of the
586
+ * standard algorithm:
587
+ *
588
+ * BN_mod_exp_mont 33 .. 40 % [AMD K6-2, Linux, debug configuration]
589
+ * 55 .. 77 % [UltraSparc processor, but
590
+ * debug-solaris-sparcv8-gcc conf.]
591
+ *
592
+ * BN_mod_exp_recp 50 .. 70 % [AMD K6-2, Linux, debug configuration]
593
+ * 62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc]
594
+ *
595
+ * On the Sparc, BN_mod_exp_recp was faster than BN_mod_exp_mont
596
+ * at 2048 and more bits, but at 512 and 1024 bits, it was
597
+ * slower even than the standard algorithm!
598
+ *
599
+ * "Real" timings [linux-elf, solaris-sparcv9-gcc configurations]
600
+ * should be obtained when the new Montgomery reduction code
601
+ * has been integrated into OpenSSL.) */
602
+
603
+ if (BN_is_odd(m)) {
604
+ if (a->top == 1 && !a->neg && BN_get_flags(p, BN_FLG_CONSTTIME) == 0) {
605
+ BN_ULONG A = a->d[0];
606
+ return BN_mod_exp_mont_word(r, A, p, m, ctx, NULL);
607
+ }
608
+
609
+ return BN_mod_exp_mont(r, a, p, m, ctx, NULL);
610
+ }
611
+
612
+ return mod_exp_recp(r, a, p, m, ctx);
613
+ }
614
+
615
+ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
616
+ const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont) {
617
+ int i, j, bits, ret = 0, wstart, window;
618
+ int start = 1;
619
+ BIGNUM *d, *r;
620
+ const BIGNUM *aa;
621
+ /* Table of variables obtained from 'ctx' */
622
+ BIGNUM *val[TABLE_SIZE];
623
+ BN_MONT_CTX *new_mont = NULL;
624
+
625
+ if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
626
+ return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, mont);
627
+ }
628
+
629
+ if (!BN_is_odd(m)) {
630
+ OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
631
+ return 0;
632
+ }
633
+ bits = BN_num_bits(p);
634
+ if (bits == 0) {
635
+ ret = BN_one(rr);
636
+ return ret;
637
+ }
638
+
639
+ BN_CTX_start(ctx);
640
+ d = BN_CTX_get(ctx);
641
+ r = BN_CTX_get(ctx);
642
+ val[0] = BN_CTX_get(ctx);
643
+ if (!d || !r || !val[0]) {
644
+ goto err;
645
+ }
646
+
647
+ /* Allocate a montgomery context if it was not supplied by the caller. */
648
+ if (mont == NULL) {
649
+ new_mont = BN_MONT_CTX_new();
650
+ if (new_mont == NULL || !BN_MONT_CTX_set(new_mont, m, ctx)) {
651
+ goto err;
652
+ }
653
+ mont = new_mont;
654
+ }
655
+
656
+ if (a->neg || BN_ucmp(a, m) >= 0) {
657
+ if (!BN_nnmod(val[0], a, m, ctx)) {
658
+ goto err;
659
+ }
660
+ aa = val[0];
661
+ } else {
662
+ aa = a;
663
+ }
664
+
665
+ if (BN_is_zero(aa)) {
666
+ BN_zero(rr);
667
+ ret = 1;
668
+ goto err;
669
+ }
670
+ if (!BN_to_montgomery(val[0], aa, mont, ctx)) {
671
+ goto err; /* 1 */
672
+ }
673
+
674
+ window = BN_window_bits_for_exponent_size(bits);
675
+ if (window > 1) {
676
+ if (!BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx)) {
677
+ goto err; /* 2 */
678
+ }
679
+ j = 1 << (window - 1);
680
+ for (i = 1; i < j; i++) {
681
+ if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
682
+ !BN_mod_mul_montgomery(val[i], val[i - 1], d, mont, ctx)) {
683
+ goto err;
684
+ }
685
+ }
686
+ }
687
+
688
+ start = 1; /* This is used to avoid multiplication etc
689
+ * when there is only the value '1' in the
690
+ * buffer. */
691
+ wstart = bits - 1; /* The top bit of the window */
692
+
693
+ j = m->top; /* borrow j */
694
+ if (m->d[j - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) {
695
+ if (bn_wexpand(r, j) == NULL) {
696
+ goto err;
697
+ }
698
+ /* 2^(top*BN_BITS2) - m */
699
+ r->d[0] = (0 - m->d[0]) & BN_MASK2;
700
+ for (i = 1; i < j; i++) {
701
+ r->d[i] = (~m->d[i]) & BN_MASK2;
702
+ }
703
+ r->top = j;
704
+ /* Upper words will be zero if the corresponding words of 'm'
705
+ * were 0xfff[...], so decrement r->top accordingly. */
706
+ bn_correct_top(r);
707
+ } else if (!BN_to_montgomery(r, BN_value_one(), mont, ctx)) {
708
+ goto err;
709
+ }
710
+
711
+ for (;;) {
712
+ int wvalue; /* The 'value' of the window */
713
+ int wend; /* The bottom bit of the window */
714
+
715
+ if (BN_is_bit_set(p, wstart) == 0) {
716
+ if (!start && !BN_mod_mul_montgomery(r, r, r, mont, ctx)) {
717
+ goto err;
718
+ }
719
+ if (wstart == 0) {
720
+ break;
721
+ }
722
+ wstart--;
723
+ continue;
724
+ }
725
+
726
+ /* We now have wstart on a 'set' bit, we now need to work out how bit a
727
+ * window to do. To do this we need to scan forward until the last set bit
728
+ * before the end of the window */
729
+ wvalue = 1;
730
+ wend = 0;
731
+ for (i = 1; i < window; i++) {
732
+ if (wstart - i < 0) {
733
+ break;
734
+ }
735
+ if (BN_is_bit_set(p, wstart - i)) {
736
+ wvalue <<= (i - wend);
737
+ wvalue |= 1;
738
+ wend = i;
739
+ }
740
+ }
741
+
742
+ /* wend is the size of the current window */
743
+ j = wend + 1;
744
+ /* add the 'bytes above' */
745
+ if (!start) {
746
+ for (i = 0; i < j; i++) {
747
+ if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) {
748
+ goto err;
749
+ }
750
+ }
751
+ }
752
+
753
+ /* wvalue will be an odd number < 2^window */
754
+ if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx)) {
755
+ goto err;
756
+ }
757
+
758
+ /* move the 'window' down further */
759
+ wstart -= wend + 1;
760
+ start = 0;
761
+ if (wstart < 0) {
762
+ break;
763
+ }
764
+ }
765
+
766
+ if (!BN_from_montgomery(rr, r, mont, ctx)) {
767
+ goto err;
768
+ }
769
+ ret = 1;
770
+
771
+ err:
772
+ BN_MONT_CTX_free(new_mont);
773
+ BN_CTX_end(ctx);
774
+ return ret;
775
+ }
776
+
777
+ /* BN_mod_exp_mont_consttime() stores the precomputed powers in a specific
778
+ * layout so that accessing any of these table values shows the same access
779
+ * pattern as far as cache lines are concerned. The following functions are
780
+ * used to transfer a BIGNUM from/to that table. */
781
+ static int copy_to_prebuf(const BIGNUM *b, int top, unsigned char *buf, int idx,
782
+ int width) {
783
+ size_t i, j;
784
+
785
+ if (top > b->top) {
786
+ top = b->top; /* this works because 'buf' is explicitly zeroed */
787
+ }
788
+ for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) {
789
+ buf[j] = ((unsigned char *)b->d)[i];
790
+ }
791
+
792
+ return 1;
793
+ }
794
+
795
+ static int copy_from_prebuf(BIGNUM *b, int top, unsigned char *buf, int idx,
796
+ int width) {
797
+ size_t i, j;
798
+
799
+ if (bn_wexpand(b, top) == NULL) {
800
+ return 0;
801
+ }
802
+
803
+ for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) {
804
+ ((unsigned char *)b->d)[i] = buf[j];
805
+ }
806
+
807
+ b->top = top;
808
+ bn_correct_top(b);
809
+ return 1;
810
+ }
811
+
812
+ /* BN_mod_exp_mont_conttime is based on the assumption that the L1 data cache
813
+ * line width of the target processor is at least the following value. */
814
+ #define MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH (64)
815
+ #define MOD_EXP_CTIME_MIN_CACHE_LINE_MASK \
816
+ (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - 1)
817
+
818
+ /* Window sizes optimized for fixed window size modular exponentiation
819
+ * algorithm (BN_mod_exp_mont_consttime).
820
+ *
821
+ * To achieve the security goals of BN_mode_exp_mont_consttime, the maximum
822
+ * size of the window must not exceed
823
+ * log_2(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH).
824
+ *
825
+ * Window size thresholds are defined for cache line sizes of 32 and 64, cache
826
+ * line sizes where log_2(32)=5 and log_2(64)=6 respectively. A window size of
827
+ * 7 should only be used on processors that have a 128 byte or greater cache
828
+ * line size. */
829
+ #if MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 64
830
+
831
+ #define BN_window_bits_for_ctime_exponent_size(b) \
832
+ ((b) > 937 ? 6 : (b) > 306 ? 5 : (b) > 89 ? 4 : (b) > 22 ? 3 : 1)
833
+ #define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (6)
834
+
835
+ #elif MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 32
836
+
837
+ #define BN_window_bits_for_ctime_exponent_size(b) \
838
+ ((b) > 306 ? 5 : (b) > 89 ? 4 : (b) > 22 ? 3 : 1)
839
+ #define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (5)
840
+
841
+ #endif
842
+
843
+ /* Given a pointer value, compute the next address that is a cache line
844
+ * multiple. */
845
+ #define MOD_EXP_CTIME_ALIGN(x_) \
846
+ ((unsigned char *)(x_) + \
847
+ (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - \
848
+ (((size_t)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK))))
849
+
850
+ /* This variant of BN_mod_exp_mont() uses fixed windows and the special
851
+ * precomputation memory layout to limit data-dependency to a minimum
852
+ * to protect secret exponents (cf. the hyper-threading timing attacks
853
+ * pointed out by Colin Percival,
854
+ * http://www.daemonology.net/hyperthreading-considered-harmful/)
855
+ */
856
+ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
857
+ const BIGNUM *m, BN_CTX *ctx,
858
+ const BN_MONT_CTX *mont) {
859
+ int i, bits, ret = 0, window, wvalue;
860
+ int top;
861
+ BN_MONT_CTX *new_mont = NULL;
862
+
863
+ int numPowers;
864
+ unsigned char *powerbufFree = NULL;
865
+ int powerbufLen = 0;
866
+ unsigned char *powerbuf = NULL;
867
+ BIGNUM tmp, am;
868
+
869
+ if (!BN_is_odd(m)) {
870
+ OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
871
+ return 0;
872
+ }
873
+
874
+ top = m->top;
875
+
876
+ bits = BN_num_bits(p);
877
+ if (bits == 0) {
878
+ ret = BN_one(rr);
879
+ return ret;
880
+ }
881
+
882
+ BN_CTX_start(ctx);
883
+
884
+ /* Allocate a montgomery context if it was not supplied by the caller. */
885
+ if (mont == NULL) {
886
+ new_mont = BN_MONT_CTX_new();
887
+ if (new_mont == NULL || !BN_MONT_CTX_set(new_mont, m, ctx)) {
888
+ goto err;
889
+ }
890
+ mont = new_mont;
891
+ }
892
+
893
+ #ifdef RSAZ_ENABLED
894
+ /* If the size of the operands allow it, perform the optimized
895
+ * RSAZ exponentiation. For further information see
896
+ * crypto/bn/rsaz_exp.c and accompanying assembly modules. */
897
+ if ((16 == a->top) && (16 == p->top) && (BN_num_bits(m) == 1024) &&
898
+ rsaz_avx2_eligible()) {
899
+ if (NULL == bn_wexpand(rr, 16)) {
900
+ goto err;
901
+ }
902
+ RSAZ_1024_mod_exp_avx2(rr->d, a->d, p->d, m->d, mont->RR.d, mont->n0[0]);
903
+ rr->top = 16;
904
+ rr->neg = 0;
905
+ bn_correct_top(rr);
906
+ ret = 1;
907
+ goto err;
908
+ }
909
+ #endif
910
+
911
+ /* Get the window size to use with size of p. */
912
+ window = BN_window_bits_for_ctime_exponent_size(bits);
913
+ #if defined(OPENSSL_BN_ASM_MONT5)
914
+ if (window >= 5) {
915
+ window = 5; /* ~5% improvement for RSA2048 sign, and even for RSA4096 */
916
+ if ((top & 7) == 0) {
917
+ powerbufLen += 2 * top * sizeof(m->d[0]);
918
+ }
919
+ }
920
+ #endif
921
+
922
+ /* Allocate a buffer large enough to hold all of the pre-computed
923
+ * powers of am, am itself and tmp.
924
+ */
925
+ numPowers = 1 << window;
926
+ powerbufLen +=
927
+ sizeof(m->d[0]) *
928
+ (top * numPowers + ((2 * top) > numPowers ? (2 * top) : numPowers));
929
+ #ifdef alloca
930
+ if (powerbufLen < 3072) {
931
+ powerbufFree = alloca(powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH);
932
+ } else
933
+ #endif
934
+ {
935
+ if ((powerbufFree = (unsigned char *)OPENSSL_malloc(
936
+ powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL) {
937
+ goto err;
938
+ }
939
+ }
940
+
941
+ powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree);
942
+ memset(powerbuf, 0, powerbufLen);
943
+
944
+ #ifdef alloca
945
+ if (powerbufLen < 3072) {
946
+ powerbufFree = NULL;
947
+ }
948
+ #endif
949
+
950
+ /* lay down tmp and am right after powers table */
951
+ tmp.d = (BN_ULONG *)(powerbuf + sizeof(m->d[0]) * top * numPowers);
952
+ am.d = tmp.d + top;
953
+ tmp.top = am.top = 0;
954
+ tmp.dmax = am.dmax = top;
955
+ tmp.neg = am.neg = 0;
956
+ tmp.flags = am.flags = BN_FLG_STATIC_DATA;
957
+
958
+ /* prepare a^0 in Montgomery domain */
959
+ /* by Shay Gueron's suggestion */
960
+ if (m->d[top - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) {
961
+ /* 2^(top*BN_BITS2) - m */
962
+ tmp.d[0] = (0 - m->d[0]) & BN_MASK2;
963
+ for (i = 1; i < top; i++) {
964
+ tmp.d[i] = (~m->d[i]) & BN_MASK2;
965
+ }
966
+ tmp.top = top;
967
+ } else if (!BN_to_montgomery(&tmp, BN_value_one(), mont, ctx)) {
968
+ goto err;
969
+ }
970
+
971
+ /* prepare a^1 in Montgomery domain */
972
+ if (a->neg || BN_ucmp(a, m) >= 0) {
973
+ if (!BN_mod(&am, a, m, ctx) ||
974
+ !BN_to_montgomery(&am, &am, mont, ctx)) {
975
+ goto err;
976
+ }
977
+ } else if (!BN_to_montgomery(&am, a, mont, ctx)) {
978
+ goto err;
979
+ }
980
+
981
+ #if defined(OPENSSL_BN_ASM_MONT5)
982
+ /* This optimization uses ideas from http://eprint.iacr.org/2011/239,
983
+ * specifically optimization of cache-timing attack countermeasures
984
+ * and pre-computation optimization. */
985
+
986
+ /* Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as
987
+ * 512-bit RSA is hardly relevant, we omit it to spare size... */
988
+ if (window == 5 && top > 1) {
989
+ const BN_ULONG *np = mont->N.d, *n0 = mont->n0, *np2;
990
+
991
+ /* BN_to_montgomery can contaminate words above .top
992
+ * [in BN_DEBUG[_DEBUG] build]... */
993
+ for (i = am.top; i < top; i++) {
994
+ am.d[i] = 0;
995
+ }
996
+ for (i = tmp.top; i < top; i++) {
997
+ tmp.d[i] = 0;
998
+ }
999
+
1000
+ if (top & 7) {
1001
+ np2 = np;
1002
+ } else {
1003
+ BN_ULONG *np_double = am.d + top;
1004
+ for (i = 0; i < top; i++) {
1005
+ np_double[2 * i] = np[i];
1006
+ }
1007
+ np2 = np_double;
1008
+ }
1009
+
1010
+ bn_scatter5(tmp.d, top, powerbuf, 0);
1011
+ bn_scatter5(am.d, am.top, powerbuf, 1);
1012
+ bn_mul_mont(tmp.d, am.d, am.d, np, n0, top);
1013
+ bn_scatter5(tmp.d, top, powerbuf, 2);
1014
+
1015
+ /* same as above, but uses squaring for 1/2 of operations */
1016
+ for (i = 4; i < 32; i *= 2) {
1017
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
1018
+ bn_scatter5(tmp.d, top, powerbuf, i);
1019
+ }
1020
+ for (i = 3; i < 8; i += 2) {
1021
+ int j;
1022
+ bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np2, n0, top, i - 1);
1023
+ bn_scatter5(tmp.d, top, powerbuf, i);
1024
+ for (j = 2 * i; j < 32; j *= 2) {
1025
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
1026
+ bn_scatter5(tmp.d, top, powerbuf, j);
1027
+ }
1028
+ }
1029
+ for (; i < 16; i += 2) {
1030
+ bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np2, n0, top, i - 1);
1031
+ bn_scatter5(tmp.d, top, powerbuf, i);
1032
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
1033
+ bn_scatter5(tmp.d, top, powerbuf, 2 * i);
1034
+ }
1035
+ for (; i < 32; i += 2) {
1036
+ bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np2, n0, top, i - 1);
1037
+ bn_scatter5(tmp.d, top, powerbuf, i);
1038
+ }
1039
+
1040
+ bits--;
1041
+ for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--) {
1042
+ wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
1043
+ }
1044
+ bn_gather5(tmp.d, top, powerbuf, wvalue);
1045
+
1046
+ /* At this point |bits| is 4 mod 5 and at least -1. (|bits| is the first bit
1047
+ * that has not been read yet.) */
1048
+ assert(bits >= -1 && (bits == -1 || bits % 5 == 4));
1049
+
1050
+ /* Scan the exponent one window at a time starting from the most
1051
+ * significant bits.
1052
+ */
1053
+ if (top & 7) {
1054
+ while (bits >= 0) {
1055
+ for (wvalue = 0, i = 0; i < 5; i++, bits--) {
1056
+ wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
1057
+ }
1058
+
1059
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
1060
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
1061
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
1062
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
1063
+ bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
1064
+ bn_mul_mont_gather5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue);
1065
+ }
1066
+ } else {
1067
+ const uint8_t *p_bytes = (const uint8_t *)p->d;
1068
+ int max_bits = p->top * BN_BITS2;
1069
+ assert(bits < max_bits);
1070
+ /* |p = 0| has been handled as a special case, so |max_bits| is at least
1071
+ * one word. */
1072
+ assert(max_bits >= 64);
1073
+
1074
+ /* If the first bit to be read lands in the last byte, unroll the first
1075
+ * iteration to avoid reading past the bounds of |p->d|. (After the first
1076
+ * iteration, we are guaranteed to be past the last byte.) Note |bits|
1077
+ * here is the top bit, inclusive. */
1078
+ if (bits - 4 >= max_bits - 8) {
1079
+ /* Read five bits from |bits-4| through |bits|, inclusive. */
1080
+ wvalue = p_bytes[p->top * BN_BYTES - 1];
1081
+ wvalue >>= (bits - 4) & 7;
1082
+ wvalue &= 0x1f;
1083
+ bits -= 5;
1084
+ bn_power5(tmp.d, tmp.d, powerbuf, np2, n0, top, wvalue);
1085
+ }
1086
+ while (bits >= 0) {
1087
+ /* Read five bits from |bits-4| through |bits|, inclusive. */
1088
+ int first_bit = bits - 4;
1089
+ wvalue = *(const uint16_t *) (p_bytes + (first_bit >> 3));
1090
+ wvalue >>= first_bit & 7;
1091
+ wvalue &= 0x1f;
1092
+ bits -= 5;
1093
+ bn_power5(tmp.d, tmp.d, powerbuf, np2, n0, top, wvalue);
1094
+ }
1095
+ }
1096
+
1097
+ ret = bn_from_montgomery(tmp.d, tmp.d, NULL, np2, n0, top);
1098
+ tmp.top = top;
1099
+ bn_correct_top(&tmp);
1100
+ if (ret) {
1101
+ if (!BN_copy(rr, &tmp)) {
1102
+ ret = 0;
1103
+ }
1104
+ goto err; /* non-zero ret means it's not error */
1105
+ }
1106
+ } else
1107
+ #endif
1108
+ {
1109
+ if (!copy_to_prebuf(&tmp, top, powerbuf, 0, numPowers) ||
1110
+ !copy_to_prebuf(&am, top, powerbuf, 1, numPowers)) {
1111
+ goto err;
1112
+ }
1113
+
1114
+ /* If the window size is greater than 1, then calculate
1115
+ * val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1)
1116
+ * (even powers could instead be computed as (a^(i/2))^2
1117
+ * to use the slight performance advantage of sqr over mul).
1118
+ */
1119
+ if (window > 1) {
1120
+ if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx) ||
1121
+ !copy_to_prebuf(&tmp, top, powerbuf, 2, numPowers)) {
1122
+ goto err;
1123
+ }
1124
+ for (i = 3; i < numPowers; i++) {
1125
+ /* Calculate a^i = a^(i-1) * a */
1126
+ if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx) ||
1127
+ !copy_to_prebuf(&tmp, top, powerbuf, i, numPowers)) {
1128
+ goto err;
1129
+ }
1130
+ }
1131
+ }
1132
+
1133
+ bits--;
1134
+ for (wvalue = 0, i = bits % window; i >= 0; i--, bits--) {
1135
+ wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
1136
+ }
1137
+ if (!copy_from_prebuf(&tmp, top, powerbuf, wvalue, numPowers)) {
1138
+ goto err;
1139
+ }
1140
+
1141
+ /* Scan the exponent one window at a time starting from the most
1142
+ * significant bits.
1143
+ */
1144
+ while (bits >= 0) {
1145
+ wvalue = 0; /* The 'value' of the window */
1146
+
1147
+ /* Scan the window, squaring the result as we go */
1148
+ for (i = 0; i < window; i++, bits--) {
1149
+ if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp, mont, ctx)) {
1150
+ goto err;
1151
+ }
1152
+ wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
1153
+ }
1154
+
1155
+ /* Fetch the appropriate pre-computed value from the pre-buf */
1156
+ if (!copy_from_prebuf(&am, top, powerbuf, wvalue, numPowers)) {
1157
+ goto err;
1158
+ }
1159
+
1160
+ /* Multiply the result into the intermediate result */
1161
+ if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx)) {
1162
+ goto err;
1163
+ }
1164
+ }
1165
+ }
1166
+
1167
+ /* Convert the final result from montgomery to standard format */
1168
+ if (!BN_from_montgomery(rr, &tmp, mont, ctx)) {
1169
+ goto err;
1170
+ }
1171
+ ret = 1;
1172
+
1173
+ err:
1174
+ BN_MONT_CTX_free(new_mont);
1175
+ if (powerbuf != NULL) {
1176
+ OPENSSL_cleanse(powerbuf, powerbufLen);
1177
+ OPENSSL_free(powerbufFree);
1178
+ }
1179
+ BN_CTX_end(ctx);
1180
+ return (ret);
1181
+ }
1182
+
1183
+ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
1184
+ const BIGNUM *m, BN_CTX *ctx,
1185
+ const BN_MONT_CTX *mont) {
1186
+ BN_MONT_CTX *new_mont = NULL;
1187
+ int b, bits, ret = 0;
1188
+ int r_is_one;
1189
+ BN_ULONG w, next_w;
1190
+ BIGNUM *d, *r, *t;
1191
+ BIGNUM *swap_tmp;
1192
+ #define BN_MOD_MUL_WORD(r, w, m) \
1193
+ (BN_mul_word(r, (w)) && \
1194
+ (/* BN_ucmp(r, (m)) < 0 ? 1 :*/ \
1195
+ (BN_mod(t, r, m, ctx) && (swap_tmp = r, r = t, t = swap_tmp, 1))))
1196
+ /* BN_MOD_MUL_WORD is only used with 'w' large, so the BN_ucmp test is
1197
+ * probably more overhead than always using BN_mod (which uses BN_copy if a
1198
+ * similar test returns true). We can use BN_mod and do not need BN_nnmod
1199
+ * because our accumulator is never negative (the result of BN_mod does not
1200
+ * depend on the sign of the modulus). */
1201
+ #define BN_TO_MONTGOMERY_WORD(r, w, mont) \
1202
+ (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx))
1203
+
1204
+ if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
1205
+ /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
1206
+ OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1207
+ return 0;
1208
+ }
1209
+
1210
+ if (!BN_is_odd(m)) {
1211
+ OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
1212
+ return 0;
1213
+ }
1214
+
1215
+ if (m->top == 1) {
1216
+ a %= m->d[0]; /* make sure that 'a' is reduced */
1217
+ }
1218
+
1219
+ bits = BN_num_bits(p);
1220
+ if (bits == 0) {
1221
+ /* x**0 mod 1 is still zero. */
1222
+ if (BN_is_one(m)) {
1223
+ ret = 1;
1224
+ BN_zero(rr);
1225
+ } else {
1226
+ ret = BN_one(rr);
1227
+ }
1228
+ return ret;
1229
+ }
1230
+ if (a == 0) {
1231
+ BN_zero(rr);
1232
+ ret = 1;
1233
+ return ret;
1234
+ }
1235
+
1236
+ BN_CTX_start(ctx);
1237
+ d = BN_CTX_get(ctx);
1238
+ r = BN_CTX_get(ctx);
1239
+ t = BN_CTX_get(ctx);
1240
+ if (d == NULL || r == NULL || t == NULL) {
1241
+ goto err;
1242
+ }
1243
+
1244
+ /* Allocate a montgomery context if it was not supplied by the caller. */
1245
+ if (mont == NULL) {
1246
+ new_mont = BN_MONT_CTX_new();
1247
+ if (new_mont == NULL || !BN_MONT_CTX_set(new_mont, m, ctx)) {
1248
+ goto err;
1249
+ }
1250
+ mont = new_mont;
1251
+ }
1252
+
1253
+ r_is_one = 1; /* except for Montgomery factor */
1254
+
1255
+ /* bits-1 >= 0 */
1256
+
1257
+ /* The result is accumulated in the product r*w. */
1258
+ w = a; /* bit 'bits-1' of 'p' is always set */
1259
+ for (b = bits - 2; b >= 0; b--) {
1260
+ /* First, square r*w. */
1261
+ next_w = w * w;
1262
+ if ((next_w / w) != w) {
1263
+ /* overflow */
1264
+ if (r_is_one) {
1265
+ if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) {
1266
+ goto err;
1267
+ }
1268
+ r_is_one = 0;
1269
+ } else {
1270
+ if (!BN_MOD_MUL_WORD(r, w, m)) {
1271
+ goto err;
1272
+ }
1273
+ }
1274
+ next_w = 1;
1275
+ }
1276
+
1277
+ w = next_w;
1278
+ if (!r_is_one) {
1279
+ if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) {
1280
+ goto err;
1281
+ }
1282
+ }
1283
+
1284
+ /* Second, multiply r*w by 'a' if exponent bit is set. */
1285
+ if (BN_is_bit_set(p, b)) {
1286
+ next_w = w * a;
1287
+ if ((next_w / a) != w) {
1288
+ /* overflow */
1289
+ if (r_is_one) {
1290
+ if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) {
1291
+ goto err;
1292
+ }
1293
+ r_is_one = 0;
1294
+ } else {
1295
+ if (!BN_MOD_MUL_WORD(r, w, m)) {
1296
+ goto err;
1297
+ }
1298
+ }
1299
+ next_w = a;
1300
+ }
1301
+ w = next_w;
1302
+ }
1303
+ }
1304
+
1305
+ /* Finally, set r:=r*w. */
1306
+ if (w != 1) {
1307
+ if (r_is_one) {
1308
+ if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) {
1309
+ goto err;
1310
+ }
1311
+ r_is_one = 0;
1312
+ } else {
1313
+ if (!BN_MOD_MUL_WORD(r, w, m)) {
1314
+ goto err;
1315
+ }
1316
+ }
1317
+ }
1318
+
1319
+ if (r_is_one) {
1320
+ /* can happen only if a == 1*/
1321
+ if (!BN_one(rr)) {
1322
+ goto err;
1323
+ }
1324
+ } else {
1325
+ if (!BN_from_montgomery(rr, r, mont, ctx)) {
1326
+ goto err;
1327
+ }
1328
+ }
1329
+ ret = 1;
1330
+
1331
+ err:
1332
+ BN_MONT_CTX_free(new_mont);
1333
+ BN_CTX_end(ctx);
1334
+ return ret;
1335
+ }