1 /*
2 Copyright (c) 2021 Fraunhofer AISEC. See the COPYRIGHT
3 file at the top-level directory of this distribution.
4
5 Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 option. This file may not be copied, modified, or distributed
9 except according to those terms.
10 */
11
12 #include <stdio.h>
13
14 #include "oscore.h"
15
16 #include "oscore/oscore_cose.h"
17 #include "oscore/security_context.h"
18
19 #include "common/crypto_wrapper.h"
20 #include "common/memcpy_s.h"
21 #include "common/print_util.h"
22
23 #include "cbor/oscore_enc_structure.h"
24
25 /*the additional bytes in the enc_structure are constant*/
26 #define ENCRYPT0_ENCODING_OVERHEAD 16
27
28 /**
29 * @brief Encode the input AAD to defined COSE structure
30 * @param external_aad: input aad to form COSE structure
31 * @param out: output encoded COSE byte string
32 * @return err
33 */
create_enc_structure(struct byte_array * external_aad,struct byte_array * out)34 static enum err create_enc_structure(struct byte_array *external_aad,
35 struct byte_array *out)
36 {
37 struct oscore_enc_structure enc_structure;
38
39 uint8_t context[] = { "Encrypt0" };
40 enc_structure.oscore_enc_structure_context.value = context;
41 enc_structure.oscore_enc_structure_context.len =
42 (uint32_t)strlen((char *)context);
43 enc_structure.oscore_enc_structure_protected.value = NULL;
44 enc_structure.oscore_enc_structure_protected.len = 0;
45 enc_structure.oscore_enc_structure_external_aad.value =
46 external_aad->ptr;
47 enc_structure.oscore_enc_structure_external_aad.len =
48 external_aad->len;
49
50 size_t payload_len_out = 0;
51
52 TRY_EXPECT(cbor_encode_oscore_enc_structure(out->ptr, out->len,
53 &enc_structure,
54 &payload_len_out),
55 0);
56
57 out->len = (uint32_t)payload_len_out;
58 return ok;
59 }
60
oscore_cose_decrypt(struct byte_array * in_ciphertext,struct byte_array * out_plaintext,struct byte_array * nonce,struct byte_array * recipient_aad,struct byte_array * key)61 enum err oscore_cose_decrypt(struct byte_array *in_ciphertext,
62 struct byte_array *out_plaintext,
63 struct byte_array *nonce,
64 struct byte_array *recipient_aad,
65 struct byte_array *key)
66 {
67 /* get enc_structure */
68 uint32_t aad_len = recipient_aad->len + ENCRYPT0_ENCODING_OVERHEAD;
69 BYTE_ARRAY_NEW(aad, MAX_AAD_LEN, aad_len);
70 TRY(create_enc_structure(recipient_aad, &aad));
71 PRINT_ARRAY("AAD encoded", aad.ptr, aad.len);
72 struct byte_array tag = BYTE_ARRAY_INIT(
73 (in_ciphertext->ptr + in_ciphertext->len - 8), 8);
74
75 PRINT_ARRAY("Ciphertext", in_ciphertext->ptr, in_ciphertext->len);
76
77 TRY(aead(DECRYPT, in_ciphertext, key, nonce, &aad, out_plaintext,
78 &tag));
79
80 PRINT_ARRAY("Decrypted plaintext", out_plaintext->ptr,
81 out_plaintext->len);
82 return ok;
83 }
84
oscore_cose_encrypt(struct byte_array * in_plaintext,struct byte_array * out_ciphertext,struct byte_array * nonce,struct byte_array * sender_aad,struct byte_array * key)85 enum err oscore_cose_encrypt(struct byte_array *in_plaintext,
86 struct byte_array *out_ciphertext,
87 struct byte_array *nonce,
88 struct byte_array *sender_aad,
89 struct byte_array *key)
90 {
91 /* get enc_structure */
92 uint32_t aad_len = sender_aad->len + ENCRYPT0_ENCODING_OVERHEAD;
93 BYTE_ARRAY_NEW(aad, MAX_AAD_LEN, aad_len);
94
95 TRY(create_enc_structure(sender_aad, &aad));
96 PRINT_ARRAY("aad enc structure", aad.ptr, aad.len);
97
98 struct byte_array tag =
99 BYTE_ARRAY_INIT(out_ciphertext->ptr + in_plaintext->len, 8);
100
101 out_ciphertext->len -= tag.len;
102 TRY(aead(ENCRYPT, in_plaintext, key, nonce, &aad, out_ciphertext,
103 &tag));
104
105 PRINT_ARRAY("tag", tag.ptr, tag.len);
106 PRINT_ARRAY("Ciphertext", out_ciphertext->ptr, out_ciphertext->len);
107 out_ciphertext->len += tag.len;
108 PRINT_ARRAY("Ciphertext + tag", out_ciphertext->ptr,
109 out_ciphertext->len);
110
111 return ok;
112 }
113