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/pickle_encoding.h" |
17 | |
18 | #include "olm/base64.h" |
19 | #include "olm/cipher.h" |
20 | #include "olm/olm.h" |
21 | |
22 | static const struct _olm_cipher_aes_sha_256 PICKLE_CIPHER = |
23 | OLM_CIPHER_INIT_AES_SHA_256("Pickle" ); |
24 | |
25 | size_t _olm_enc_output_length( |
26 | size_t raw_length |
27 | ) { |
28 | const struct _olm_cipher *cipher = OLM_CIPHER_BASE(&PICKLE_CIPHER); |
29 | size_t length = cipher->ops->encrypt_ciphertext_length(cipher, raw_length); |
30 | length += cipher->ops->mac_length(cipher); |
31 | return _olm_encode_base64_length(input_length: length); |
32 | } |
33 | |
34 | uint8_t * _olm_enc_output_pos( |
35 | uint8_t * output, |
36 | size_t raw_length |
37 | ) { |
38 | const struct _olm_cipher *cipher = OLM_CIPHER_BASE(&PICKLE_CIPHER); |
39 | size_t length = cipher->ops->encrypt_ciphertext_length(cipher, raw_length); |
40 | length += cipher->ops->mac_length(cipher); |
41 | return output + _olm_encode_base64_length(input_length: length) - length; |
42 | } |
43 | |
44 | size_t _olm_enc_output( |
45 | uint8_t const * key, size_t key_length, |
46 | uint8_t * output, size_t raw_length |
47 | ) { |
48 | const struct _olm_cipher *cipher = OLM_CIPHER_BASE(&PICKLE_CIPHER); |
49 | size_t ciphertext_length = cipher->ops->encrypt_ciphertext_length( |
50 | cipher, raw_length |
51 | ); |
52 | size_t length = ciphertext_length + cipher->ops->mac_length(cipher); |
53 | size_t base64_length = _olm_encode_base64_length(input_length: length); |
54 | uint8_t * raw_output = output + base64_length - length; |
55 | cipher->ops->encrypt( |
56 | cipher, |
57 | key, key_length, |
58 | raw_output, raw_length, |
59 | raw_output, ciphertext_length, |
60 | raw_output, length |
61 | ); |
62 | _olm_encode_base64(input: raw_output, input_length: length, output); |
63 | return base64_length; |
64 | } |
65 | |
66 | |
67 | size_t _olm_enc_input(uint8_t const * key, size_t key_length, |
68 | uint8_t * input, size_t b64_length, |
69 | enum OlmErrorCode * last_error |
70 | ) { |
71 | size_t enc_length = _olm_decode_base64_length(input_length: b64_length); |
72 | if (enc_length == (size_t)-1) { |
73 | if (last_error) { |
74 | *last_error = OLM_INVALID_BASE64; |
75 | } |
76 | return (size_t)-1; |
77 | } |
78 | _olm_decode_base64(input, input_length: b64_length, output: input); |
79 | const struct _olm_cipher *cipher = OLM_CIPHER_BASE(&PICKLE_CIPHER); |
80 | size_t raw_length = enc_length - cipher->ops->mac_length(cipher); |
81 | size_t result = cipher->ops->decrypt( |
82 | cipher, |
83 | key, key_length, |
84 | input, enc_length, |
85 | input, raw_length, |
86 | input, raw_length |
87 | ); |
88 | if (result == (size_t)-1 && last_error) { |
89 | *last_error = OLM_BAD_ACCOUNT_KEY; |
90 | } |
91 | return result; |
92 | } |
93 | |