1 /*
2 * Copyright (c) 2020 Siddharth Chandrasekaran <siddharth@embedjournal.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <ctype.h>
8
9 #include <zephyr/device.h>
10 #include <zephyr/sys/crc.h>
11 #include <zephyr/logging/log.h>
12
13 #ifdef CONFIG_OSDP_SC_ENABLED
14 #include <zephyr/crypto/crypto.h>
15 #include <zephyr/random/random.h>
16 #endif
17
18 #include "osdp_common.h"
19
20 LOG_MODULE_DECLARE(osdp, CONFIG_OSDP_LOG_LEVEL);
21
osdp_dump(const char * head,uint8_t * buf,int len)22 void osdp_dump(const char *head, uint8_t *buf, int len)
23 {
24 LOG_HEXDUMP_DBG(buf, len, head);
25 }
26
osdp_compute_crc16(const uint8_t * buf,size_t len)27 uint16_t osdp_compute_crc16(const uint8_t *buf, size_t len)
28 {
29 return crc16_itu_t(0x1D0F, buf, len);
30 }
31
osdp_millis_now(void)32 int64_t osdp_millis_now(void)
33 {
34 return (int64_t) k_uptime_get();
35 }
36
osdp_millis_since(int64_t last)37 int64_t osdp_millis_since(int64_t last)
38 {
39 int64_t tmp = last;
40
41 return (int64_t) k_uptime_delta(&tmp);
42 }
43
osdp_keyset_complete(struct osdp_pd * pd)44 void osdp_keyset_complete(struct osdp_pd *pd)
45 {
46 cp_keyset_complete(pd);
47 }
48
49 #ifdef CONFIG_OSDP_SC_ENABLED
50
osdp_encrypt(uint8_t * key,uint8_t * iv,uint8_t * data,int len)51 void osdp_encrypt(uint8_t *key, uint8_t *iv, uint8_t *data, int len)
52 {
53 const struct device *dev;
54 struct cipher_ctx ctx = {
55 .keylen = 16,
56 .key.bit_stream = key,
57 .flags = CAP_NO_IV_PREFIX
58 };
59 struct cipher_pkt encrypt = {
60 .in_buf = data,
61 .in_len = len,
62 .out_buf = data,
63 .out_len = len
64 };
65
66 dev = device_get_binding(CONFIG_OSDP_CRYPTO_DRV_NAME);
67 if (dev == NULL) {
68 LOG_ERR("Failed to get crypto dev binding!");
69 return;
70 }
71
72 if (iv != NULL) {
73 if (cipher_begin_session(dev, &ctx,
74 CRYPTO_CIPHER_ALGO_AES,
75 CRYPTO_CIPHER_MODE_CBC,
76 CRYPTO_CIPHER_OP_ENCRYPT)) {
77 LOG_ERR("Failed at cipher_begin_session");
78 return;
79 }
80 if (cipher_cbc_op(&ctx, &encrypt, iv)) {
81 LOG_ERR("CBC ENCRYPT - Failed");
82 }
83 } else {
84 if (cipher_begin_session(dev, &ctx,
85 CRYPTO_CIPHER_ALGO_AES,
86 CRYPTO_CIPHER_MODE_ECB,
87 CRYPTO_CIPHER_OP_ENCRYPT)) {
88 LOG_ERR("Failed at cipher_begin_session");
89 return;
90 }
91 if (cipher_block_op(&ctx, &encrypt)) {
92 LOG_ERR("ECB ENCRYPT - Failed");
93 }
94 }
95 cipher_free_session(dev, &ctx);
96 }
97
osdp_decrypt(uint8_t * key,uint8_t * iv,uint8_t * data,int len)98 void osdp_decrypt(uint8_t *key, uint8_t *iv, uint8_t *data, int len)
99 {
100 const struct device *dev;
101 struct cipher_ctx ctx = {
102 .keylen = 16,
103 .key.bit_stream = key,
104 .flags = CAP_NO_IV_PREFIX
105 };
106 struct cipher_pkt decrypt = {
107 .in_buf = data,
108 .in_len = len,
109 .out_buf = data,
110 .out_len = len
111 };
112
113 dev = device_get_binding(CONFIG_OSDP_CRYPTO_DRV_NAME);
114 if (dev == NULL) {
115 LOG_ERR("Failed to get crypto dev binding!");
116 return;
117 }
118
119 if (iv != NULL) {
120 if (cipher_begin_session(dev, &ctx,
121 CRYPTO_CIPHER_ALGO_AES,
122 CRYPTO_CIPHER_MODE_CBC,
123 CRYPTO_CIPHER_OP_DECRYPT)) {
124 LOG_ERR("Failed at cipher_begin_session");
125 return;
126 }
127 if (cipher_cbc_op(&ctx, &decrypt, iv)) {
128 LOG_ERR("CBC DECRYPT - Failed");
129 }
130 } else {
131 if (cipher_begin_session(dev, &ctx,
132 CRYPTO_CIPHER_ALGO_AES,
133 CRYPTO_CIPHER_MODE_ECB,
134 CRYPTO_CIPHER_OP_DECRYPT)) {
135 LOG_ERR("Failed at cipher_begin_session");
136 return;
137 }
138 if (cipher_block_op(&ctx, &decrypt)) {
139 LOG_ERR("ECB DECRYPT - Failed");
140 }
141 }
142 cipher_free_session(dev, &ctx);
143 }
144
osdp_fill_random(uint8_t * buf,int len)145 void osdp_fill_random(uint8_t *buf, int len)
146 {
147 sys_csrand_get(buf, len);
148 }
149
osdp_get_sc_status_mask(void)150 uint32_t osdp_get_sc_status_mask(void)
151 {
152 int i;
153 uint32_t mask = 0;
154 struct osdp_pd *pd;
155 struct osdp *ctx = osdp_get_ctx();
156
157 for (i = 0; i < NUM_PD(ctx); i++) {
158 pd = osdp_to_pd(ctx, i);
159 if (ISSET_FLAG(pd, PD_FLAG_SC_ACTIVE)) {
160 mask |= 1 << i;
161 }
162 }
163 return mask;
164 }
165
166 #endif /* CONFIG_OSDP_SC_ENABLED */
167