ruby_olm 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }