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
22static const struct _olm_cipher_aes_sha_256 PICKLE_CIPHER =
23 OLM_CIPHER_INIT_AES_SHA_256("Pickle");
24
25size_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
34uint8_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
44size_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
67size_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