Compare commits

..

4 Commits

Author SHA1 Message Date
Cyberes 8fae0cd5db fix some things 2024-07-03 19:01:19 -06:00
Cyberes 09602b2745 update gitignore 2024-07-02 22:09:02 -06:00
Cyberes 06d0c28499 adjust a few encryption things 2024-07-02 21:18:25 -06:00
Cyberes 28603b2a2e payload checksum must always be 2 symbols
ad300ec784
2024-07-02 18:24:25 -06:00
7 changed files with 59 additions and 64 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
.idea .idea
server/config.yml server/config.yml
.vscode .vscode
*.ino.cpp
# ---> Python # ---> Python
# Byte-compiled / optimized / DLL files # Byte-compiled / optimized / DLL files

View File

@ -257,11 +257,10 @@ bool TeleClientUDP::notify(byte event, const char* payload)
if (wifi.connected()) if (wifi.connected())
{ {
#if SERVER_ENCRYPTION_ENABLE == 1 #if SERVER_ENCRYPTION_ENABLE == 1
char *orig_send_buf = netbuf.buffer(); unsigned int encrypted_len;
unsigned int orig_send_buf_len = netbuf.length(); unsigned char* encrypted_buf = encrypt_buffer(netbuf.buffer(), netbuf.length(), &encrypted_len);
unsigned char encrypted_buf[12 + orig_send_buf_len + 16]; bool wifi_send = wifi.send((const char *)encrypted_buf, encrypted_len);
encrypt_string((unsigned char *)orig_send_buf, orig_send_buf_len, encrypted_buf); free(encrypted_buf);
if (!wifi.send((const char *)encrypted_buf, sizeof(encrypted_buf))) break;
#else #else
if (!wifi.send(netbuf.buffer(), netbuf.length())) break; if (!wifi.send(netbuf.buffer(), netbuf.length())) break;
#endif #endif
@ -270,11 +269,11 @@ bool TeleClientUDP::notify(byte event, const char* payload)
#endif #endif
{ {
#if SERVER_ENCRYPTION_ENABLE == 1 #if SERVER_ENCRYPTION_ENABLE == 1
char *orig_send_buf = netbuf.buffer(); unsigned int encrypted_len;
unsigned int orig_send_buf_len = netbuf.length(); unsigned char* encrypted_buf = encrypt_buffer(netbuf.buffer(), netbuf.length(), &encrypted_len);
unsigned char encrypted_buf[12 + orig_send_buf_len + 16]; bool cell_send = cell.send((const char *)encrypted_buf, encrypted_len);
encrypt_string((unsigned char *)orig_send_buf, orig_send_buf_len, encrypted_buf); free(encrypted_buf);
if (!cell.send((const char *)encrypted_buf, sizeof(encrypted_buf))) break; if (!cell_send) break;
#else #else
if (!cell.send(netbuf.buffer(), netbuf.length())) break; if (!cell.send(netbuf.buffer(), netbuf.length())) break;
#endif #endif

View File

@ -66,32 +66,10 @@ void decrypt_string(const unsigned char *input, size_t length, unsigned char *ou
size_t decryptedLength = length - sizeof(nonce) - chachaPoly.tagSize(); size_t decryptedLength = length - sizeof(nonce) - chachaPoly.tagSize();
chachaPoly.decrypt(output, input + sizeof(nonce), decryptedLength); chachaPoly.decrypt(output, input + sizeof(nonce), decryptedLength);
// String decryptedString = "";
// for (size_t i = 0; i < decryptedLength; i++) {
// decryptedString += (char)output[i];
// }
// Serial.println(decryptedString);
const unsigned char *tagPtr = input + sizeof(nonce) + decryptedLength; // actual tag const unsigned char *tagPtr = input + sizeof(nonce) + decryptedLength; // actual tag
uint8_t computedTag[16]; // computed tag uint8_t computedTag[16]; // computed tag
chachaPoly.computeTag(computedTag, sizeof(computedTag)); chachaPoly.computeTag(computedTag, sizeof(computedTag));
// Serial.print("Tag: ");
// for (size_t i = 0; i < chachaPoly.tagSize(); i++) {
// Serial.print(tagPtr[i], HEX);
// Serial.print(" ");
// }
// Serial.println();
// Serial.print("Computed Tag: ");
// for (size_t i = 0; i < sizeof(computedTag); i++) {
// Serial.print(computedTag[i], HEX);
// Serial.print(" ");
// }
// Serial.println();
///// BEGIN TAG VERIFY
// The crypto library implementation of tag verification crashes.
// Can never match if the expected tag length is too long. // Can never match if the expected tag length is too long.
if (chachaPoly.tagSize() > 16) { if (chachaPoly.tagSize() > 16) {
Serial.println("[CHACHA] Authentication failed: expected tag length is too long"); Serial.println("[CHACHA] Authentication failed: expected tag length is too long");
@ -100,17 +78,28 @@ void decrypt_string(const unsigned char *input, size_t length, unsigned char *ou
} }
// Compute the tag and check it. // Compute the tag and check it.
// The crypto library implementation of tag verification crashes.
bool equal = secure_compare(computedTag, tagPtr, chachaPoly.tagSize()); bool equal = secure_compare(computedTag, tagPtr, chachaPoly.tagSize());
clean(computedTag); clean(computedTag);
if (!equal) { if (!equal) {
Serial.println("[CHACHA] Authentication failed!"); Serial.println("[CHACHA] Authentication failed!");
output[0] = '\0'; output[0] = '\0';
return; return;
} }
///// END TAG VERIFY
output[decryptedLength] = '\0'; output[decryptedLength] = '\0';
chachaPoly.clear(); chachaPoly.clear();
} }
unsigned char* encrypt_buffer(char* buf, unsigned int len, unsigned int* encrypted_len) {
// Increase the size of encrypted_buf to hold the nonce, the encrypted data, and the authentication tag.
unsigned char* encrypted_buf = (unsigned char*)malloc(12 + len + 16); // 12 bytes for nonce and 16 bytes for tag
if(!encrypted_buf) {
// handle error
return NULL;
}
encrypt_string((unsigned char *)buf, len, encrypted_buf);
*encrypted_len = 12 + len + 16;
return encrypted_buf;
}

View File

@ -7,3 +7,4 @@
void encrypt_string(const unsigned char *input, size_t length, unsigned char *output); void encrypt_string(const unsigned char *input, size_t length, unsigned char *output);
void decrypt_string(const unsigned char *input, size_t length, unsigned char *output); void decrypt_string(const unsigned char *input, size_t length, unsigned char *output);
void print_hex(const unsigned char *data, size_t length); void print_hex(const unsigned char *data, size_t length);
unsigned char* encrypt_buffer(char* buf, unsigned int len, unsigned int* encrypted_len);

View File

@ -62,6 +62,12 @@ PID_POLLING_INFO obdData[]= {
{PID_TIMING_ADVANCE, 2}, {PID_TIMING_ADVANCE, 2},
{PID_COOLANT_TEMP, 3}, {PID_COOLANT_TEMP, 3},
{PID_INTAKE_TEMP, 3}, {PID_INTAKE_TEMP, 3},
{PID_ODOMETER, 3},
{PID_DISTANCE, 3},
{PID_AMBIENT_TEMP, 2},
{PID_ENGINE_OIL_TEMP, 2},
{PID_FUEL_LEVEL, 1}
}; };
CBufferManager bufman; CBufferManager bufman;
@ -1007,12 +1013,11 @@ void telemetry(void* inst)
#endif #endif
#if SERVER_ENCRYPTION_ENABLE == 1 #if SERVER_ENCRYPTION_ENABLE == 1
char *orig_send_buf = store.buffer(); unsigned int encrypted_len;
unsigned int orig_send_buf_len = store.length(); unsigned char* encrypted_buf = encrypt_buffer(store.buffer(), store.length(), &encrypted_len);
// Increase the size of encrypted_buf to hold the nonce, the encrypted data, and the authentication tag. bool transmit_success = teleClient.transmit((const char *)encrypted_buf, encrypted_len);
unsigned char encrypted_buf[12 + orig_send_buf_len + 16]; // 12 bytes for nonce and 16 bytes for tag free(encrypted_buf);
encrypt_string((unsigned char *)orig_send_buf, orig_send_buf_len, encrypted_buf); if (transmit_success) {
if (teleClient.transmit((const char *)encrypted_buf, sizeof(encrypted_buf))) {
#else #else
if (teleClient.transmit(store.buffer(), store.length())) { if (teleClient.transmit(store.buffer(), store.length())) {
#endif #endif

View File

@ -107,7 +107,7 @@ void CStorageRAM::header(const char* devid)
void CStorageRAM::tailer() void CStorageRAM::tailer()
{ {
if (m_cache[m_cacheBytes - 1] == ',') m_cacheBytes--; if (m_cache[m_cacheBytes - 1] == ',') m_cacheBytes--;
m_cacheBytes += sprintf(m_cache + m_cacheBytes, "*%X", (unsigned int)checksum(m_cache, m_cacheBytes)); m_cacheBytes += sprintf(m_cache + m_cacheBytes, "*%02X", (unsigned int)checksum(m_cache, m_cacheBytes));
} }
void CStorageRAM::untailer() void CStorageRAM::untailer()

View File

@ -84,21 +84,22 @@ func main() {
// Handle the message. // Handle the message.
go func(addr *net.UDPAddr, buf []byte, n int) { go func(addr *net.UDPAddr, buf []byte, n int) {
// Do the decryption.
var plaintext []byte var plaintext []byte
if len(buf[:n]) > 0 { shouldEncrypt := true
plaintext, err = encryption.Decrypt(key, buf[:n]) // Use only the part of the buffer that has data. recievedContent := buf[:n]
if len(recievedContent) > 0 {
plaintext, err = encryption.Decrypt(key, recievedContent) // Use only the part of the buffer that has data.
if err != nil { if err != nil {
rawHex := hex.EncodeToString(buf[:n]) logger.Warningf(formatLogMsg(addr.IP.String(), dest.Address, dest.Port, fmt.Sprintf(`Error decrypting message: %s. Length: %d, Raw: "%s"`, err, len(recievedContent), recievedContent)))
logger.Warnf(formatLogMsg(addr.IP.String(), dest.Address, dest.Port, fmt.Sprintf(`Error decrypting message: %s. Length: %d, Raw: "%s"`, err, len(rawHex), rawHex))) plaintext = recievedContent // Don't bother with decryption.
plaintext = buf[:n] // Forward the raw message to the backend without bothering with decryption. shouldEncrypt = false
if len(plaintext) > 0 { } else {
logger.Warningf("Encryption failed, possibly recieved unencrypted message -- %s", plaintext) logger.Infof(formatLogMsg(addr.IP.String(), dest.Address, dest.Port, string(plaintext)))
}
} }
} else { } else {
// If empty message. // If empty message.
plaintext = buf[:n] plaintext = recievedContent
shouldEncrypt = false
} }
forwardAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", dest.Address, dest.Port)) forwardAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", dest.Address, dest.Port))
@ -107,14 +108,12 @@ func main() {
return return
} }
// Create a new UDP address for listening to the backend server's response.
listenAddr, err := net.ResolveUDPAddr("udp", ":0") // Let the OS pick a free port. listenAddr, err := net.ResolveUDPAddr("udp", ":0") // Let the OS pick a free port.
if err != nil { if err != nil {
logger.Fatalln("Error resolving listen address:", err) logger.Fatalln("Error resolving listen address:", err)
return return
} }
// Create a new UDP listener for the backend server's response.
listenConn, err := net.ListenUDP("udp", listenAddr) listenConn, err := net.ListenUDP("udp", listenAddr)
if err != nil { if err != nil {
logger.Fatalln("Error listening for backend response:", err) logger.Fatalln("Error listening for backend response:", err)
@ -122,7 +121,6 @@ func main() {
} }
defer listenConn.Close() defer listenConn.Close()
// Dial the backend server without binding a local address.
forwardConn, err := net.DialUDP("udp", nil, forwardAddr) forwardConn, err := net.DialUDP("udp", nil, forwardAddr)
if err != nil { if err != nil {
logger.Fatalln("Error dialing to forward address:", err) logger.Fatalln("Error dialing to forward address:", err)
@ -145,11 +143,15 @@ func main() {
return return
} }
// Encrypt the backend's response. var encryptedBackendResponse []byte
encryptedBackendResponse, err := encryption.Encrypt(key, backendResponse[:n]) if shouldEncrypt {
if err != nil { encryptedBackendResponse, err = encryption.Encrypt(key, backendResponse[:n])
logger.Errorf(formatLogMsg(addr.IP.String(), dest.Address, dest.Port, fmt.Sprintf("Error encrypting response: %s", err))) if err != nil {
return logger.Errorf(formatLogMsg(addr.IP.String(), dest.Address, dest.Port, fmt.Sprintf("Error encrypting response: %s", err)))
return
}
} else {
encryptedBackendResponse = backendResponse
} }
// Forward the encrypted backend response to the client. // Forward the encrypted backend response to the client.
@ -158,8 +160,6 @@ func main() {
logger.Errorf(formatLogMsg(addr.IP.String(), dest.Address, dest.Port, fmt.Sprintf("Error forwarding response to client: %s", err))) logger.Errorf(formatLogMsg(addr.IP.String(), dest.Address, dest.Port, fmt.Sprintf("Error forwarding response to client: %s", err)))
return return
} }
logger.Infof(formatLogMsg(addr.IP.String(), dest.Address, dest.Port, string(plaintext)))
}(addr, buf, n) }(addr, buf, n)
} }
}(port, dest) }(port, dest)