ruby_olm 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (194) hide show
  1. checksums.yaml +7 -0
  2. data/ext/ruby_olm/ext_lib_olm/ext_account.c +274 -0
  3. data/ext/ruby_olm/ext_lib_olm/ext_lib_olm.c +51 -0
  4. data/ext/ruby_olm/ext_lib_olm/ext_lib_olm.h +13 -0
  5. data/ext/ruby_olm/ext_lib_olm/ext_session.c +363 -0
  6. data/ext/ruby_olm/ext_lib_olm/ext_utility.c +69 -0
  7. data/ext/ruby_olm/ext_lib_olm/extconf.rb +69 -0
  8. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_account.cpp +695 -0
  9. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_account.h +56 -0
  10. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_inbound_group_session.cpp +654 -0
  11. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_inbound_group_session.h +51 -0
  12. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_jni.h +81 -0
  13. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_jni_helper.cpp +224 -0
  14. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_jni_helper.h +30 -0
  15. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_manager.cpp +35 -0
  16. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_manager.h +36 -0
  17. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_outbound_group_session.cpp +563 -0
  18. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_outbound_group_session.h +49 -0
  19. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_pk.cpp +716 -0
  20. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_pk.h +48 -0
  21. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_session.cpp +977 -0
  22. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_session.h +59 -0
  23. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_utility.cpp +236 -0
  24. data/ext/ruby_olm/ext_lib_olm/olm/android/olm-sdk/src/main/jni/olm_utility.h +40 -0
  25. data/ext/ruby_olm/ext_lib_olm/olm/fuzzers/fuzz_decode_message.cpp +14 -0
  26. data/ext/ruby_olm/ext_lib_olm/olm/fuzzers/fuzz_decrypt.cpp +65 -0
  27. data/ext/ruby_olm/ext_lib_olm/olm/fuzzers/fuzz_group_decrypt.cpp +73 -0
  28. data/ext/ruby_olm/ext_lib_olm/olm/fuzzers/fuzz_unpickle_account.cpp +14 -0
  29. data/ext/ruby_olm/ext_lib_olm/olm/fuzzers/fuzz_unpickle_session.cpp +14 -0
  30. data/ext/ruby_olm/ext_lib_olm/olm/fuzzers/include/fuzzing.hh +82 -0
  31. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/account.hh +160 -0
  32. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/base64.h +77 -0
  33. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/base64.hh +63 -0
  34. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/cipher.h +138 -0
  35. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/crypto.h +202 -0
  36. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/error.h +72 -0
  37. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/inbound_group_session.h +235 -0
  38. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/list.hh +119 -0
  39. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/megolm.h +95 -0
  40. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/memory.h +41 -0
  41. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/memory.hh +90 -0
  42. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/message.h +93 -0
  43. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/message.hh +138 -0
  44. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/olm.h +451 -0
  45. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/olm.hh +4 -0
  46. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/outbound_group_session.h +181 -0
  47. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/pickle.h +90 -0
  48. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/pickle.hh +149 -0
  49. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/pickle_encoding.h +76 -0
  50. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/pk.h +214 -0
  51. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/ratchet.hh +184 -0
  52. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/session.hh +156 -0
  53. data/ext/ruby_olm/ext_lib_olm/olm/include/olm/utility.hh +61 -0
  54. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/aes.c +1073 -0
  55. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/aes.h +123 -0
  56. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/aes_test.c +276 -0
  57. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/arcfour.c +45 -0
  58. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/arcfour.h +30 -0
  59. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/arcfour_test.c +47 -0
  60. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/base64.c +135 -0
  61. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/base64.h +27 -0
  62. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/base64_test.c +54 -0
  63. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/blowfish.c +269 -0
  64. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/blowfish.h +32 -0
  65. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/blowfish_test.c +68 -0
  66. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/des.c +269 -0
  67. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/des.h +37 -0
  68. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/des_test.c +83 -0
  69. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/md2.c +104 -0
  70. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/md2.h +33 -0
  71. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/md2_test.c +58 -0
  72. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/md5.c +189 -0
  73. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/md5.h +34 -0
  74. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/md5_test.c +60 -0
  75. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/rot-13.c +35 -0
  76. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/rot-13.h +20 -0
  77. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/rot-13_test.c +44 -0
  78. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/sha1.c +149 -0
  79. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/sha1.h +35 -0
  80. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/sha1_test.c +58 -0
  81. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/sha256.c +159 -0
  82. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/sha256.h +34 -0
  83. data/ext/ruby_olm/ext_lib_olm/olm/lib/crypto-algorithms/sha256_test.c +61 -0
  84. data/ext/ruby_olm/ext_lib_olm/olm/lib/curve25519-donna/contrib/Curve25519Donna.c +118 -0
  85. data/ext/ruby_olm/ext_lib_olm/olm/lib/curve25519-donna/contrib/Curve25519Donna.h +53 -0
  86. data/ext/ruby_olm/ext_lib_olm/olm/lib/curve25519-donna/curve25519-donna-c64.c +449 -0
  87. data/ext/ruby_olm/ext_lib_olm/olm/lib/curve25519-donna/curve25519-donna.c +860 -0
  88. data/ext/ruby_olm/ext_lib_olm/olm/lib/curve25519-donna/python-src/curve25519/curve25519module.c +105 -0
  89. data/ext/ruby_olm/ext_lib_olm/olm/lib/curve25519-donna/speed-curve25519.c +50 -0
  90. data/ext/ruby_olm/ext_lib_olm/olm/lib/curve25519-donna/test-curve25519.c +54 -0
  91. data/ext/ruby_olm/ext_lib_olm/olm/lib/curve25519-donna/test-noncanon.c +39 -0
  92. data/ext/ruby_olm/ext_lib_olm/olm/lib/curve25519-donna/test-sc-curve25519.c +72 -0
  93. data/ext/ruby_olm/ext_lib_olm/olm/lib/curve25519-donna.h +18 -0
  94. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/add_scalar.c +56 -0
  95. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/ed25519.h +38 -0
  96. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/fe.c +1493 -0
  97. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/fe.h +41 -0
  98. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/fixedint.h +72 -0
  99. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/ge.c +467 -0
  100. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/ge.h +74 -0
  101. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/key_exchange.c +79 -0
  102. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/keypair.c +16 -0
  103. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/precomp_data.h +1391 -0
  104. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/sc.c +814 -0
  105. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/sc.h +12 -0
  106. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/seed.c +40 -0
  107. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/sha512.c +275 -0
  108. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/sha512.h +21 -0
  109. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/sign.c +31 -0
  110. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/src/verify.c +77 -0
  111. data/ext/ruby_olm/ext_lib_olm/olm/lib/ed25519/test.c +150 -0
  112. data/ext/ruby_olm/ext_lib_olm/olm/python/dummy/stddef.h +0 -0
  113. data/ext/ruby_olm/ext_lib_olm/olm/python/dummy/stdint.h +0 -0
  114. data/ext/ruby_olm/ext_lib_olm/olm/src/account.cpp +380 -0
  115. data/ext/ruby_olm/ext_lib_olm/olm/src/base64.cpp +167 -0
  116. data/ext/ruby_olm/ext_lib_olm/olm/src/cipher.cpp +152 -0
  117. data/ext/ruby_olm/ext_lib_olm/olm/src/crypto.cpp +299 -0
  118. data/ext/ruby_olm/ext_lib_olm/olm/src/ed25519.c +22 -0
  119. data/ext/ruby_olm/ext_lib_olm/olm/src/error.c +44 -0
  120. data/ext/ruby_olm/ext_lib_olm/olm/src/inbound_group_session.c +524 -0
  121. data/ext/ruby_olm/ext_lib_olm/olm/src/megolm.c +150 -0
  122. data/ext/ruby_olm/ext_lib_olm/olm/src/memory.cpp +45 -0
  123. data/ext/ruby_olm/ext_lib_olm/olm/src/message.cpp +401 -0
  124. data/ext/ruby_olm/ext_lib_olm/olm/src/olm.cpp +738 -0
  125. data/ext/ruby_olm/ext_lib_olm/olm/src/outbound_group_session.c +363 -0
  126. data/ext/ruby_olm/ext_lib_olm/olm/src/pickle.cpp +242 -0
  127. data/ext/ruby_olm/ext_lib_olm/olm/src/pickle_encoding.c +92 -0
  128. data/ext/ruby_olm/ext_lib_olm/olm/src/pk.cpp +412 -0
  129. data/ext/ruby_olm/ext_lib_olm/olm/src/ratchet.cpp +625 -0
  130. data/ext/ruby_olm/ext_lib_olm/olm/src/session.cpp +462 -0
  131. data/ext/ruby_olm/ext_lib_olm/olm/src/utility.cpp +57 -0
  132. data/ext/ruby_olm/ext_lib_olm/olm/tests/include/unittest.hh +107 -0
  133. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_base64.cpp +70 -0
  134. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_crypto.cpp +246 -0
  135. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_group_session.cpp +329 -0
  136. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_list.cpp +92 -0
  137. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_megolm.cpp +134 -0
  138. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_message.cpp +112 -0
  139. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_olm.cpp +405 -0
  140. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_olm_decrypt.cpp +90 -0
  141. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_olm_sha256.cpp +20 -0
  142. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_olm_signature.cpp +81 -0
  143. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_olm_using_malloc.cpp +210 -0
  144. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_pk.cpp +166 -0
  145. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_ratchet.cpp +221 -0
  146. data/ext/ruby_olm/ext_lib_olm/olm/tests/test_session.cpp +144 -0
  147. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMAccount.h +51 -0
  148. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMAccount_Private.h +25 -0
  149. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMInboundGroupSession.h +38 -0
  150. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMKit.h +37 -0
  151. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMMessage.h +38 -0
  152. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMOutboundGroupSession.h +32 -0
  153. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMPkDecryption.h +71 -0
  154. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMPkEncryption.h +42 -0
  155. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMPkMessage.h +31 -0
  156. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMSerializable.h +29 -0
  157. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMSession.h +44 -0
  158. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMSession_Private.h +26 -0
  159. data/ext/ruby_olm/ext_lib_olm/olm/xcode/OLMKit/OLMUtility.h +49 -0
  160. data/ext/ruby_olm/ext_lib_olm/staging/account.cpp +380 -0
  161. data/ext/ruby_olm/ext_lib_olm/staging/aes.c +1073 -0
  162. data/ext/ruby_olm/ext_lib_olm/staging/base64.cpp +167 -0
  163. data/ext/ruby_olm/ext_lib_olm/staging/cipher.cpp +152 -0
  164. data/ext/ruby_olm/ext_lib_olm/staging/crypto.cpp +299 -0
  165. data/ext/ruby_olm/ext_lib_olm/staging/curve25519-donna.c +860 -0
  166. data/ext/ruby_olm/ext_lib_olm/staging/ed25519.c +22 -0
  167. data/ext/ruby_olm/ext_lib_olm/staging/error.c +44 -0
  168. data/ext/ruby_olm/ext_lib_olm/staging/inbound_group_session.c +524 -0
  169. data/ext/ruby_olm/ext_lib_olm/staging/megolm.c +150 -0
  170. data/ext/ruby_olm/ext_lib_olm/staging/memory.cpp +45 -0
  171. data/ext/ruby_olm/ext_lib_olm/staging/message.cpp +401 -0
  172. data/ext/ruby_olm/ext_lib_olm/staging/olm.cpp +738 -0
  173. data/ext/ruby_olm/ext_lib_olm/staging/outbound_group_session.c +363 -0
  174. data/ext/ruby_olm/ext_lib_olm/staging/pickle.cpp +242 -0
  175. data/ext/ruby_olm/ext_lib_olm/staging/pickle_encoding.c +92 -0
  176. data/ext/ruby_olm/ext_lib_olm/staging/pk.cpp +412 -0
  177. data/ext/ruby_olm/ext_lib_olm/staging/ratchet.cpp +625 -0
  178. data/ext/ruby_olm/ext_lib_olm/staging/session.cpp +461 -0
  179. data/ext/ruby_olm/ext_lib_olm/staging/sha256.c +159 -0
  180. data/ext/ruby_olm/ext_lib_olm/staging/utility.cpp +57 -0
  181. data/lib/ruby_olm/account.rb +42 -0
  182. data/lib/ruby_olm/message.rb +6 -0
  183. data/lib/ruby_olm/olm_error.rb +70 -0
  184. data/lib/ruby_olm/olm_message.rb +25 -0
  185. data/lib/ruby_olm/pre_key_message.rb +6 -0
  186. data/lib/ruby_olm/session.rb +16 -0
  187. data/lib/ruby_olm/version.rb +5 -0
  188. data/lib/ruby_olm.rb +10 -0
  189. data/rakefile +18 -0
  190. data/test/examples/test_bob_no_answer.rb +62 -0
  191. data/test/examples/test_exchange.rb +60 -0
  192. data/test/spec/test_account.rb +152 -0
  193. data/test/unit/test_account_methods.rb +85 -0
  194. metadata +282 -0
@@ -0,0 +1,524 @@
1
+ /* Copyright 2016 OpenMarket Ltd
2
+ *
3
+ * Licensed under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License.
5
+ * You may obtain a copy of the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS,
11
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ * See the License for the specific language governing permissions and
13
+ * limitations under the License.
14
+ */
15
+
16
+ #include "olm/inbound_group_session.h"
17
+
18
+ #include <string.h>
19
+
20
+ #include "olm/base64.h"
21
+ #include "olm/cipher.h"
22
+ #include "olm/crypto.h"
23
+ #include "olm/error.h"
24
+ #include "olm/megolm.h"
25
+ #include "olm/memory.h"
26
+ #include "olm/message.h"
27
+ #include "olm/pickle.h"
28
+ #include "olm/pickle_encoding.h"
29
+
30
+
31
+ #define OLM_PROTOCOL_VERSION 3
32
+ #define GROUP_SESSION_ID_LENGTH ED25519_PUBLIC_KEY_LENGTH
33
+ #define PICKLE_VERSION 2
34
+ #define SESSION_KEY_VERSION 2
35
+ #define SESSION_EXPORT_VERSION 1
36
+
37
+ struct OlmInboundGroupSession {
38
+ /** our earliest known ratchet value */
39
+ Megolm initial_ratchet;
40
+
41
+ /** The most recent ratchet value */
42
+ Megolm latest_ratchet;
43
+
44
+ /** The ed25519 signing key */
45
+ struct _olm_ed25519_public_key signing_key;
46
+
47
+ /**
48
+ * Have we ever seen any evidence that this is a valid session?
49
+ * (either because the original session share was signed, or because we
50
+ * have subsequently successfully decrypted a message)
51
+ *
52
+ * (We don't do anything with this currently, but we may want to bear it in
53
+ * mind when we consider handling key-shares for sessions we already know
54
+ * about.)
55
+ */
56
+ int signing_key_verified;
57
+
58
+ enum OlmErrorCode last_error;
59
+ };
60
+
61
+ size_t olm_inbound_group_session_size(void) {
62
+ return sizeof(OlmInboundGroupSession);
63
+ }
64
+
65
+ OlmInboundGroupSession * olm_inbound_group_session(
66
+ void *memory
67
+ ) {
68
+ OlmInboundGroupSession *session = memory;
69
+ olm_clear_inbound_group_session(session);
70
+ return session;
71
+ }
72
+
73
+ const char *olm_inbound_group_session_last_error(
74
+ const OlmInboundGroupSession *session
75
+ ) {
76
+ return _olm_error_to_string(session->last_error);
77
+ }
78
+
79
+ size_t olm_clear_inbound_group_session(
80
+ OlmInboundGroupSession *session
81
+ ) {
82
+ _olm_unset(session, sizeof(OlmInboundGroupSession));
83
+ return sizeof(OlmInboundGroupSession);
84
+ }
85
+
86
+ #define SESSION_EXPORT_RAW_LENGTH \
87
+ (1 + 4 + MEGOLM_RATCHET_LENGTH + ED25519_PUBLIC_KEY_LENGTH)
88
+
89
+ #define SESSION_KEY_RAW_LENGTH \
90
+ (1 + 4 + MEGOLM_RATCHET_LENGTH + ED25519_PUBLIC_KEY_LENGTH\
91
+ + ED25519_SIGNATURE_LENGTH)
92
+
93
+ static size_t _init_group_session_keys(
94
+ OlmInboundGroupSession *session,
95
+ const uint8_t *key_buf,
96
+ int export_format
97
+ ) {
98
+ const uint8_t expected_version =
99
+ (export_format ? SESSION_EXPORT_VERSION : SESSION_KEY_VERSION);
100
+ const uint8_t *ptr = key_buf;
101
+ size_t version = *ptr++;
102
+
103
+ if (version != expected_version) {
104
+ session->last_error = OLM_BAD_SESSION_KEY;
105
+ return (size_t)-1;
106
+ }
107
+
108
+ uint32_t counter = 0;
109
+ // Decode counter as a big endian 32-bit number.
110
+ for (unsigned i = 0; i < 4; i++) {
111
+ counter <<= 8; counter |= *ptr++;
112
+ }
113
+
114
+ megolm_init(&session->initial_ratchet, ptr, counter);
115
+ megolm_init(&session->latest_ratchet, ptr, counter);
116
+
117
+ ptr += MEGOLM_RATCHET_LENGTH;
118
+ memcpy(
119
+ session->signing_key.public_key, ptr, ED25519_PUBLIC_KEY_LENGTH
120
+ );
121
+ ptr += ED25519_PUBLIC_KEY_LENGTH;
122
+
123
+ if (!export_format) {
124
+ if (!_olm_crypto_ed25519_verify(&session->signing_key, key_buf,
125
+ ptr - key_buf, ptr)) {
126
+ session->last_error = OLM_BAD_SIGNATURE;
127
+ return (size_t)-1;
128
+ }
129
+
130
+ /* signed keyshare */
131
+ session->signing_key_verified = 1;
132
+ }
133
+ return 0;
134
+ }
135
+
136
+ size_t olm_init_inbound_group_session(
137
+ OlmInboundGroupSession *session,
138
+ const uint8_t * session_key, size_t session_key_length
139
+ ) {
140
+ uint8_t key_buf[SESSION_KEY_RAW_LENGTH];
141
+ size_t raw_length = _olm_decode_base64_length(session_key_length);
142
+ size_t result;
143
+
144
+ if (raw_length == (size_t)-1) {
145
+ session->last_error = OLM_INVALID_BASE64;
146
+ return (size_t)-1;
147
+ }
148
+
149
+ if (raw_length != SESSION_KEY_RAW_LENGTH) {
150
+ session->last_error = OLM_BAD_SESSION_KEY;
151
+ return (size_t)-1;
152
+ }
153
+
154
+ _olm_decode_base64(session_key, session_key_length, key_buf);
155
+ result = _init_group_session_keys(session, key_buf, 0);
156
+ _olm_unset(key_buf, SESSION_KEY_RAW_LENGTH);
157
+ return result;
158
+ }
159
+
160
+ size_t olm_import_inbound_group_session(
161
+ OlmInboundGroupSession *session,
162
+ const uint8_t * session_key, size_t session_key_length
163
+ ) {
164
+ uint8_t key_buf[SESSION_EXPORT_RAW_LENGTH];
165
+ size_t raw_length = _olm_decode_base64_length(session_key_length);
166
+ size_t result;
167
+
168
+ if (raw_length == (size_t)-1) {
169
+ session->last_error = OLM_INVALID_BASE64;
170
+ return (size_t)-1;
171
+ }
172
+
173
+ if (raw_length != SESSION_EXPORT_RAW_LENGTH) {
174
+ session->last_error = OLM_BAD_SESSION_KEY;
175
+ return (size_t)-1;
176
+ }
177
+
178
+ _olm_decode_base64(session_key, session_key_length, key_buf);
179
+ result = _init_group_session_keys(session, key_buf, 1);
180
+ _olm_unset(key_buf, SESSION_EXPORT_RAW_LENGTH);
181
+ return result;
182
+ }
183
+
184
+ static size_t raw_pickle_length(
185
+ const OlmInboundGroupSession *session
186
+ ) {
187
+ size_t length = 0;
188
+ length += _olm_pickle_uint32_length(PICKLE_VERSION);
189
+ length += megolm_pickle_length(&session->initial_ratchet);
190
+ length += megolm_pickle_length(&session->latest_ratchet);
191
+ length += _olm_pickle_ed25519_public_key_length(&session->signing_key);
192
+ length += _olm_pickle_bool_length(session->signing_key_verified);
193
+ return length;
194
+ }
195
+
196
+ size_t olm_pickle_inbound_group_session_length(
197
+ const OlmInboundGroupSession *session
198
+ ) {
199
+ return _olm_enc_output_length(raw_pickle_length(session));
200
+ }
201
+
202
+ size_t olm_pickle_inbound_group_session(
203
+ OlmInboundGroupSession *session,
204
+ void const * key, size_t key_length,
205
+ void * pickled, size_t pickled_length
206
+ ) {
207
+ size_t raw_length = raw_pickle_length(session);
208
+ uint8_t *pos;
209
+
210
+ if (pickled_length < _olm_enc_output_length(raw_length)) {
211
+ session->last_error = OLM_OUTPUT_BUFFER_TOO_SMALL;
212
+ return (size_t)-1;
213
+ }
214
+
215
+ pos = _olm_enc_output_pos(pickled, raw_length);
216
+ pos = _olm_pickle_uint32(pos, PICKLE_VERSION);
217
+ pos = megolm_pickle(&session->initial_ratchet, pos);
218
+ pos = megolm_pickle(&session->latest_ratchet, pos);
219
+ pos = _olm_pickle_ed25519_public_key(pos, &session->signing_key);
220
+ pos = _olm_pickle_bool(pos, session->signing_key_verified);
221
+
222
+ return _olm_enc_output(key, key_length, pickled, raw_length);
223
+ }
224
+
225
+ size_t olm_unpickle_inbound_group_session(
226
+ OlmInboundGroupSession *session,
227
+ void const * key, size_t key_length,
228
+ void * pickled, size_t pickled_length
229
+ ) {
230
+ const uint8_t *pos;
231
+ const uint8_t *end;
232
+ uint32_t pickle_version;
233
+
234
+ size_t raw_length = _olm_enc_input(
235
+ key, key_length, pickled, pickled_length, &(session->last_error)
236
+ );
237
+ if (raw_length == (size_t)-1) {
238
+ return raw_length;
239
+ }
240
+
241
+ pos = pickled;
242
+ end = pos + raw_length;
243
+ pos = _olm_unpickle_uint32(pos, end, &pickle_version);
244
+ if (pickle_version < 1 || pickle_version > PICKLE_VERSION) {
245
+ session->last_error = OLM_UNKNOWN_PICKLE_VERSION;
246
+ return (size_t)-1;
247
+ }
248
+ pos = megolm_unpickle(&session->initial_ratchet, pos, end);
249
+ pos = megolm_unpickle(&session->latest_ratchet, pos, end);
250
+ pos = _olm_unpickle_ed25519_public_key(pos, end, &session->signing_key);
251
+
252
+ if (pickle_version == 1) {
253
+ /* pickle v1 had no signing_key_verified field (all keyshares were
254
+ * verified at import time) */
255
+ session->signing_key_verified = 1;
256
+ } else {
257
+ pos = _olm_unpickle_bool(pos, end, &(session->signing_key_verified));
258
+ }
259
+
260
+ if (end != pos) {
261
+ /* We had the wrong number of bytes in the input. */
262
+ session->last_error = OLM_CORRUPTED_PICKLE;
263
+ return (size_t)-1;
264
+ }
265
+
266
+ return pickled_length;
267
+ }
268
+
269
+ /**
270
+ * get the max plaintext length in an un-base64-ed message
271
+ */
272
+ static size_t _decrypt_max_plaintext_length(
273
+ OlmInboundGroupSession *session,
274
+ uint8_t * message, size_t message_length
275
+ ) {
276
+ struct _OlmDecodeGroupMessageResults decoded_results;
277
+
278
+ _olm_decode_group_message(
279
+ message, message_length,
280
+ megolm_cipher->ops->mac_length(megolm_cipher),
281
+ ED25519_SIGNATURE_LENGTH,
282
+ &decoded_results);
283
+
284
+ if (decoded_results.version != OLM_PROTOCOL_VERSION) {
285
+ session->last_error = OLM_BAD_MESSAGE_VERSION;
286
+ return (size_t)-1;
287
+ }
288
+
289
+ if (!decoded_results.ciphertext) {
290
+ session->last_error = OLM_BAD_MESSAGE_FORMAT;
291
+ return (size_t)-1;
292
+ }
293
+
294
+ return megolm_cipher->ops->decrypt_max_plaintext_length(
295
+ megolm_cipher, decoded_results.ciphertext_length);
296
+ }
297
+
298
+ size_t olm_group_decrypt_max_plaintext_length(
299
+ OlmInboundGroupSession *session,
300
+ uint8_t * message, size_t message_length
301
+ ) {
302
+ size_t raw_length;
303
+
304
+ raw_length = _olm_decode_base64(message, message_length, message);
305
+ if (raw_length == (size_t)-1) {
306
+ session->last_error = OLM_INVALID_BASE64;
307
+ return (size_t)-1;
308
+ }
309
+
310
+ return _decrypt_max_plaintext_length(
311
+ session, message, raw_length
312
+ );
313
+ }
314
+
315
+ /**
316
+ * get a copy of the megolm ratchet, advanced
317
+ * to the relevant index. Returns 0 on success, -1 on error
318
+ */
319
+ static size_t _get_megolm(
320
+ OlmInboundGroupSession *session, uint32_t message_index, Megolm *result
321
+ ) {
322
+ /* pick a megolm instance to use. If we're at or beyond the latest ratchet
323
+ * value, use that */
324
+ if ((message_index - session->latest_ratchet.counter) < (1U << 31)) {
325
+ megolm_advance_to(&session->latest_ratchet, message_index);
326
+ *result = session->latest_ratchet;
327
+ return 0;
328
+ } else if ((message_index - session->initial_ratchet.counter) >= (1U << 31)) {
329
+ /* the counter is before our intial ratchet - we can't decode this. */
330
+ session->last_error = OLM_UNKNOWN_MESSAGE_INDEX;
331
+ return (size_t)-1;
332
+ } else {
333
+ /* otherwise, start from the initial megolm. Take a copy so that we
334
+ * don't overwrite the initial megolm */
335
+ *result = session->initial_ratchet;
336
+ megolm_advance_to(result, message_index);
337
+ return 0;
338
+ }
339
+ }
340
+
341
+ /**
342
+ * decrypt an un-base64-ed message
343
+ */
344
+ static size_t _decrypt(
345
+ OlmInboundGroupSession *session,
346
+ uint8_t * message, size_t message_length,
347
+ uint8_t * plaintext, size_t max_plaintext_length,
348
+ uint32_t * message_index
349
+ ) {
350
+ struct _OlmDecodeGroupMessageResults decoded_results;
351
+ size_t max_length, r;
352
+ Megolm megolm;
353
+
354
+ _olm_decode_group_message(
355
+ message, message_length,
356
+ megolm_cipher->ops->mac_length(megolm_cipher),
357
+ ED25519_SIGNATURE_LENGTH,
358
+ &decoded_results);
359
+
360
+ if (decoded_results.version != OLM_PROTOCOL_VERSION) {
361
+ session->last_error = OLM_BAD_MESSAGE_VERSION;
362
+ return (size_t)-1;
363
+ }
364
+
365
+ if (!decoded_results.has_message_index || !decoded_results.ciphertext) {
366
+ session->last_error = OLM_BAD_MESSAGE_FORMAT;
367
+ return (size_t)-1;
368
+ }
369
+
370
+ if (message_index != NULL) {
371
+ *message_index = decoded_results.message_index;
372
+ }
373
+
374
+ /* verify the signature. We could do this before decoding the message, but
375
+ * we allow for the possibility of future protocol versions which use a
376
+ * different signing mechanism; we would rather throw "BAD_MESSAGE_VERSION"
377
+ * than "BAD_SIGNATURE" in this case.
378
+ */
379
+ message_length -= ED25519_SIGNATURE_LENGTH;
380
+ r = _olm_crypto_ed25519_verify(
381
+ &session->signing_key,
382
+ message, message_length,
383
+ message + message_length
384
+ );
385
+ if (!r) {
386
+ session->last_error = OLM_BAD_SIGNATURE;
387
+ return (size_t)-1;
388
+ }
389
+
390
+ max_length = megolm_cipher->ops->decrypt_max_plaintext_length(
391
+ megolm_cipher,
392
+ decoded_results.ciphertext_length
393
+ );
394
+ if (max_plaintext_length < max_length) {
395
+ session->last_error = OLM_OUTPUT_BUFFER_TOO_SMALL;
396
+ return (size_t)-1;
397
+ }
398
+
399
+ r = _get_megolm(session, decoded_results.message_index, &megolm);
400
+ if (r == (size_t)-1) {
401
+ return r;
402
+ }
403
+
404
+ /* now try checking the mac, and decrypting */
405
+ r = megolm_cipher->ops->decrypt(
406
+ megolm_cipher,
407
+ megolm_get_data(&megolm), MEGOLM_RATCHET_LENGTH,
408
+ message, message_length,
409
+ decoded_results.ciphertext, decoded_results.ciphertext_length,
410
+ plaintext, max_plaintext_length
411
+ );
412
+
413
+ _olm_unset(&megolm, sizeof(megolm));
414
+ if (r == (size_t)-1) {
415
+ session->last_error = OLM_BAD_MESSAGE_MAC;
416
+ return r;
417
+ }
418
+
419
+ /* once we have successfully decrypted a message, set a flag to say the
420
+ * session appears valid. */
421
+ session->signing_key_verified = 1;
422
+
423
+ return r;
424
+ }
425
+
426
+ size_t olm_group_decrypt(
427
+ OlmInboundGroupSession *session,
428
+ uint8_t * message, size_t message_length,
429
+ uint8_t * plaintext, size_t max_plaintext_length,
430
+ uint32_t * message_index
431
+ ) {
432
+ size_t raw_message_length;
433
+
434
+ raw_message_length = _olm_decode_base64(message, message_length, message);
435
+ if (raw_message_length == (size_t)-1) {
436
+ session->last_error = OLM_INVALID_BASE64;
437
+ return (size_t)-1;
438
+ }
439
+
440
+ return _decrypt(
441
+ session, message, raw_message_length,
442
+ plaintext, max_plaintext_length,
443
+ message_index
444
+ );
445
+ }
446
+
447
+ size_t olm_inbound_group_session_id_length(
448
+ const OlmInboundGroupSession *session
449
+ ) {
450
+ return _olm_encode_base64_length(GROUP_SESSION_ID_LENGTH);
451
+ }
452
+
453
+ size_t olm_inbound_group_session_id(
454
+ OlmInboundGroupSession *session,
455
+ uint8_t * id, size_t id_length
456
+ ) {
457
+ if (id_length < olm_inbound_group_session_id_length(session)) {
458
+ session->last_error = OLM_OUTPUT_BUFFER_TOO_SMALL;
459
+ return (size_t)-1;
460
+ }
461
+
462
+ return _olm_encode_base64(
463
+ session->signing_key.public_key, GROUP_SESSION_ID_LENGTH, id
464
+ );
465
+ }
466
+
467
+ uint32_t olm_inbound_group_session_first_known_index(
468
+ const OlmInboundGroupSession *session
469
+ ) {
470
+ return session->initial_ratchet.counter;
471
+ }
472
+
473
+ int olm_inbound_group_session_is_verified(
474
+ const OlmInboundGroupSession *session
475
+ ) {
476
+ return session->signing_key_verified;
477
+ }
478
+
479
+ size_t olm_export_inbound_group_session_length(
480
+ const OlmInboundGroupSession *session
481
+ ) {
482
+ return _olm_encode_base64_length(SESSION_EXPORT_RAW_LENGTH);
483
+ }
484
+
485
+ size_t olm_export_inbound_group_session(
486
+ OlmInboundGroupSession *session,
487
+ uint8_t * key, size_t key_length, uint32_t message_index
488
+ ) {
489
+ uint8_t *raw;
490
+ uint8_t *ptr;
491
+ Megolm megolm;
492
+ size_t r;
493
+ size_t encoded_length = olm_export_inbound_group_session_length(session);
494
+
495
+ if (key_length < encoded_length) {
496
+ session->last_error = OLM_OUTPUT_BUFFER_TOO_SMALL;
497
+ return (size_t)-1;
498
+ }
499
+
500
+ r = _get_megolm(session, message_index, &megolm);
501
+ if (r == (size_t)-1) {
502
+ return r;
503
+ }
504
+
505
+ /* put the raw data at the end of the output buffer. */
506
+ raw = ptr = key + encoded_length - SESSION_EXPORT_RAW_LENGTH;
507
+ *ptr++ = SESSION_EXPORT_VERSION;
508
+
509
+ // Encode message index as a big endian 32-bit number.
510
+ for (unsigned i = 0; i < 4; i++) {
511
+ *ptr++ = 0xFF & (message_index >> 24); message_index <<= 8;
512
+ }
513
+
514
+ memcpy(ptr, megolm_get_data(&megolm), MEGOLM_RATCHET_LENGTH);
515
+ ptr += MEGOLM_RATCHET_LENGTH;
516
+
517
+ memcpy(
518
+ ptr, session->signing_key.public_key,
519
+ ED25519_PUBLIC_KEY_LENGTH
520
+ );
521
+ ptr += ED25519_PUBLIC_KEY_LENGTH;
522
+
523
+ return _olm_encode_base64(raw, SESSION_EXPORT_RAW_LENGTH, key);
524
+ }
@@ -0,0 +1,150 @@
1
+ /* Copyright 2016 OpenMarket Ltd
2
+ *
3
+ * Licensed under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License.
5
+ * You may obtain a copy of the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS,
11
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ * See the License for the specific language governing permissions and
13
+ * limitations under the License.
14
+ */
15
+
16
+
17
+ #include "olm/megolm.h"
18
+
19
+ #include <string.h>
20
+
21
+ #include "olm/cipher.h"
22
+ #include "olm/crypto.h"
23
+ #include "olm/pickle.h"
24
+
25
+ static const struct _olm_cipher_aes_sha_256 MEGOLM_CIPHER =
26
+ OLM_CIPHER_INIT_AES_SHA_256("MEGOLM_KEYS");
27
+ const struct _olm_cipher *megolm_cipher = OLM_CIPHER_BASE(&MEGOLM_CIPHER);
28
+
29
+ /* the seeds used in the HMAC-SHA-256 functions for each part of the ratchet.
30
+ */
31
+ #define HASH_KEY_SEED_LENGTH 1
32
+ static uint8_t HASH_KEY_SEEDS[MEGOLM_RATCHET_PARTS][HASH_KEY_SEED_LENGTH] = {
33
+ {0x00},
34
+ {0x01},
35
+ {0x02},
36
+ {0x03}
37
+ };
38
+
39
+ static void rehash_part(
40
+ uint8_t data[MEGOLM_RATCHET_PARTS][MEGOLM_RATCHET_PART_LENGTH],
41
+ int rehash_from_part, int rehash_to_part
42
+ ) {
43
+ _olm_crypto_hmac_sha256(
44
+ data[rehash_from_part],
45
+ MEGOLM_RATCHET_PART_LENGTH,
46
+ HASH_KEY_SEEDS[rehash_to_part], HASH_KEY_SEED_LENGTH,
47
+ data[rehash_to_part]
48
+ );
49
+ }
50
+
51
+
52
+
53
+ void megolm_init(Megolm *megolm, uint8_t const *random_data, uint32_t counter) {
54
+ megolm->counter = counter;
55
+ memcpy(megolm->data, random_data, MEGOLM_RATCHET_LENGTH);
56
+ }
57
+
58
+ size_t megolm_pickle_length(const Megolm *megolm) {
59
+ size_t length = 0;
60
+ length += _olm_pickle_bytes_length(megolm_get_data(megolm), MEGOLM_RATCHET_LENGTH);
61
+ length += _olm_pickle_uint32_length(megolm->counter);
62
+ return length;
63
+
64
+ }
65
+
66
+ uint8_t * megolm_pickle(const Megolm *megolm, uint8_t *pos) {
67
+ pos = _olm_pickle_bytes(pos, megolm_get_data(megolm), MEGOLM_RATCHET_LENGTH);
68
+ pos = _olm_pickle_uint32(pos, megolm->counter);
69
+ return pos;
70
+ }
71
+
72
+ const uint8_t * megolm_unpickle(Megolm *megolm, const uint8_t *pos,
73
+ const uint8_t *end) {
74
+ pos = _olm_unpickle_bytes(pos, end, (uint8_t *)(megolm->data),
75
+ MEGOLM_RATCHET_LENGTH);
76
+ pos = _olm_unpickle_uint32(pos, end, &megolm->counter);
77
+ return pos;
78
+ }
79
+
80
+ /* simplistic implementation for a single step */
81
+ void megolm_advance(Megolm *megolm) {
82
+ uint32_t mask = 0x00FFFFFF;
83
+ int h = 0;
84
+ int i;
85
+
86
+ megolm->counter++;
87
+
88
+ /* figure out how much we need to rekey */
89
+ while (h < (int)MEGOLM_RATCHET_PARTS) {
90
+ if (!(megolm->counter & mask))
91
+ break;
92
+ h++;
93
+ mask >>= 8;
94
+ }
95
+
96
+ /* now update R(h)...R(3) based on R(h) */
97
+ for (i = MEGOLM_RATCHET_PARTS-1; i >= h; i--) {
98
+ rehash_part(megolm->data, h, i);
99
+ }
100
+ }
101
+
102
+ void megolm_advance_to(Megolm *megolm, uint32_t advance_to) {
103
+ int j;
104
+
105
+ /* starting with R0, see if we need to update each part of the hash */
106
+ for (j = 0; j < (int)MEGOLM_RATCHET_PARTS; j++) {
107
+ int shift = (MEGOLM_RATCHET_PARTS-j-1) * 8;
108
+ uint32_t mask = (~(uint32_t)0) << shift;
109
+ int k;
110
+
111
+ /* how many times do we need to rehash this part?
112
+ *
113
+ * '& 0xff' ensures we handle integer wraparound correctly
114
+ */
115
+ unsigned int steps =
116
+ ((advance_to >> shift) - (megolm->counter >> shift)) & 0xff;
117
+
118
+ if (steps == 0) {
119
+ /* deal with the edge case where megolm->counter is slightly larger
120
+ * than advance_to. This should only happen for R(0), and implies
121
+ * that advance_to has wrapped around and we need to advance R(0)
122
+ * 256 times.
123
+ */
124
+ if (advance_to < megolm->counter) {
125
+ steps = 0x100;
126
+ } else {
127
+ continue;
128
+ }
129
+ }
130
+
131
+ /* for all but the last step, we can just bump R(j) without regard
132
+ * to R(j+1)...R(3).
133
+ */
134
+ while (steps > 1) {
135
+ rehash_part(megolm->data, j, j);
136
+ steps --;
137
+ }
138
+
139
+ /* on the last step we also need to bump R(j+1)...R(3).
140
+ *
141
+ * (Theoretically, we could skip bumping R(j+2) if we're going to bump
142
+ * R(j+1) again, but the code to figure that out is a bit baroque and
143
+ * doesn't save us much).
144
+ */
145
+ for (k = 3; k >= j; k--) {
146
+ rehash_part(megolm->data, j, k);
147
+ }
148
+ megolm->counter = advance_to & mask;
149
+ }
150
+ }
@@ -0,0 +1,45 @@
1
+ /* Copyright 2015 OpenMarket Ltd
2
+ *
3
+ * Licensed under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License.
5
+ * You may obtain a copy of the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS,
11
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ * See the License for the specific language governing permissions and
13
+ * limitations under the License.
14
+ */
15
+ #include "olm/memory.hh"
16
+ #include "olm/memory.h"
17
+
18
+ void _olm_unset(
19
+ void volatile * buffer, size_t buffer_length
20
+ ) {
21
+ olm::unset(buffer, buffer_length);
22
+ }
23
+
24
+ void olm::unset(
25
+ void volatile * buffer, std::size_t buffer_length
26
+ ) {
27
+ char volatile * pos = reinterpret_cast<char volatile *>(buffer);
28
+ char volatile * end = pos + buffer_length;
29
+ while (pos != end) {
30
+ *(pos++) = 0;
31
+ }
32
+ }
33
+
34
+
35
+ bool olm::is_equal(
36
+ std::uint8_t const * buffer_a,
37
+ std::uint8_t const * buffer_b,
38
+ std::size_t length
39
+ ) {
40
+ std::uint8_t volatile result = 0;
41
+ while (length--) {
42
+ result |= (*(buffer_a++)) ^ (*(buffer_b++));
43
+ }
44
+ return result == 0;
45
+ }