MeterLogger
crypto.c
Go to the documentation of this file.
1 //
2 // crypto.c
3 // crypto_test
4 //
5 // Created by stoffer on 21/06/2016.
6 // Copyright © 2016 stoffer. All rights reserved.
7 //
8 
9 #include <esp8266.h>
10 #include <string.h>
11 #include "crypto/crypto.h"
12 #include "crypto/aes.h"
13 #include "crypto/sha256.h"
14 #include "crypto/hmac-sha256.h"
15 #include "user_config.h"
16 
17 // variables passed to crypto library have to be int32_t aligned becouse they are casted and accessed as such
19 uint8_t aes_key[16];
20 uint8_t hmac_sha256_key[16];
21 
22 void init_aes_hmac_combined(uint8_t *key) {
23 #ifdef DEBUG
24  unsigned int i;
25 #endif
26  _align_32_bit uint8_t master_key[16];
27 
28  memcpy(master_key, key, 16);
29 
30 #ifdef DEBUG
32  printf("master key: ");
33  for (i = 0; i < 16; i++) {
34  printf("%02x", key[i]);
35  }
36  printf("\n");
38 #endif
39  // generate aes_key and hmac_sha256_key from master_key
40  memset(sha256_hash, 0, sizeof(sha256_hash));
41 
42  sha256_raw(master_key, 16, sha256_hash);
43 
44  // first 16 bytes is aes key
45  memcpy(aes_key, sha256_hash, sizeof(aes_key));
46  // last 16 bytes is hmac sha256 key
48 
49 #ifdef DEBUG
51  // print keys
52  printf("aes key: ");
53  for (i = 0; i < 16; i++) {
54  printf("%02x", aes_key[i]);
55  }
56  printf("\n");
57 
58  printf("hmac sha256 key: ");
59  for (i = 0; i < 16; i++) {
60  printf("%02x", hmac_sha256_key[i]);
61  }
62  printf("\n");
64 #endif
65 }
66 
68 size_t encrypt_aes_hmac_combined(uint8_t *dst, uint8_t *topic, size_t topic_l, uint8_t *message, size_t message_l) {
69  hmac_sha256_ctx_t hctx;
70  int return_l;
71 
72  // encrypt
73  memset(dst, 0, sizeof(dst));
74  // get random iv in first 16 bytes of mqtt_message
76 
77  // calculate blocks needed for encrypted string
78  return_l = message_l;
79  if (return_l % 16) {
80  return_l = (return_l / 16) * 16 + 16;
81  }
82  else {
83  return_l = (return_l / 16) * 16;
84  }
85 
86  AES128_CBC_encrypt_buffer(dst + SHA256_DIGEST_LENGTH + 16, message, return_l, aes_key, dst + SHA256_DIGEST_LENGTH); // first 32 bytes of mqtt_message contains hmac sha256, next 16 bytes contains IV
87  return_l += SHA256_DIGEST_LENGTH + 16;
88 
89  // hmac sha256
91  hmac_sha256_update(&hctx, topic, topic_l);
93  hmac_sha256_final(&hctx, dst);
94 
95  return return_l;
96 }
97 
99 size_t decrypt_aes_hmac_combined(uint8_t *dst, uint8_t *topic, size_t topic_l, uint8_t *message, size_t message_l) {
100  hmac_sha256_ctx_t hctx;
101  uint8_t calculated_hmac_sha256[SHA256_DIGEST_LENGTH];
102 
103  // hmac sha256
105  hmac_sha256_update(&hctx, topic, topic_l);
106  hmac_sha256_update(&hctx, message + SHA256_DIGEST_LENGTH, message_l - SHA256_DIGEST_LENGTH);
107  hmac_sha256_final(&hctx, calculated_hmac_sha256);
108 
109  if (memcmp(calculated_hmac_sha256, message, SHA256_DIGEST_LENGTH) == 0) {
110  // hmac sha256 matches
111 
112  AES128_CBC_decrypt_buffer(dst + 0, message + SHA256_DIGEST_LENGTH + 16, message_l, aes_key, message + SHA256_DIGEST_LENGTH);
113  return strlen(dst);
114  }
115  else {
116  return 0;
117  }
118 }
void system_soft_wdt_stop(void)
#define memset(x, a, b)
Definition: platform.h:21
uint8_t sha256_hash[SHA256_DIGEST_LENGTH]
Definition: crypto.c:18
ICACHE_FLASH_ATTR size_t decrypt_aes_hmac_combined(uint8_t *dst, uint8_t *topic, size_t topic_l, uint8_t *message, size_t message_l)
Definition: crypto.c:99
void init_aes_hmac_combined(uint8_t *key)
Definition: crypto.c:22
ICACHE_FLASH_ATTR void sha256_raw(uint8_t *data, size_t len, uint8_t digest[SHA256_DIGEST_LENGTH])
Definition: sha256.c:421
int os_get_random(unsigned char *buf, size_t len)
#define ICACHE_FLASH_ATTR
Definition: c_types.h:99
ICACHE_FLASH_ATTR void AES128_CBC_decrypt_buffer(uint8_t *output, uint8_t *input, uint32_t length, const uint8_t *key, uint8_t *iv)
ICACHE_FLASH_ATTR void hmac_sha256_update(hmac_sha256_ctx_t *hctx, uint8_t *msg, uint32_t msglen)
Definition: hmac-sha256.c:49
uint8_t hmac_sha256_key[16]
Definition: crypto.c:20
void system_soft_wdt_restart(void)
#define _align_32_bit
Definition: crypto.h:15
ICACHE_FLASH_ATTR size_t encrypt_aes_hmac_combined(uint8_t *dst, uint8_t *topic, size_t topic_l, uint8_t *message, size_t message_l)
Definition: crypto.c:68
ICACHE_FLASH_ATTR void AES128_CBC_encrypt_buffer(uint8_t *output, uint8_t *input, uint32_t length, const uint8_t *key, uint8_t *iv)
ICACHE_FLASH_ATTR void hmac_sha256_final(hmac_sha256_ctx_t *hctx, uint8_t *hmac)
Definition: hmac-sha256.c:54
static const char key[]
Definition: config.h:42
uint8_t aes_key[16]
Definition: crypto.c:19
#define memcpy(x, a, b)
Definition: platform.h:22
#define printf(...)
Definition: platform.h:13
#define memcmp(a, b, c)
Definition: platform.h:26
#define strlen(a)
Definition: platform.h:25
#define SHA256_DIGEST_LENGTH
Definition: sha256.h:39
ICACHE_FLASH_ATTR void hmac_sha256_init(hmac_sha256_ctx_t *hctx, uint8_t *key, uint32_t keylen)
Definition: hmac-sha256.c:30