moved all third-party lib to separate folder
This commit is contained in:
5
thirdparty/libcsp/src/crypto/CMakeLists.txt
vendored
Normal file
5
thirdparty/libcsp/src/crypto/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
target_sources(${LIB_CSP_NAME} PRIVATE
|
||||
csp_hmac.c
|
||||
csp_sha1.c
|
||||
csp_xtea.c
|
||||
)
|
202
thirdparty/libcsp/src/crypto/csp_hmac.c
vendored
Normal file
202
thirdparty/libcsp/src/crypto/csp_hmac.c
vendored
Normal file
@ -0,0 +1,202 @@
|
||||
/*
|
||||
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
|
||||
Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com)
|
||||
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* Hash-based Message Authentication Code - based on code from libtom.org */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/* CSP includes */
|
||||
#include <csp/csp.h>
|
||||
|
||||
#include <csp/crypto/csp_hmac.h>
|
||||
#include <csp/crypto/csp_sha1.h>
|
||||
|
||||
#ifdef CSP_USE_HMAC
|
||||
|
||||
#define HMAC_KEY_LENGTH 16
|
||||
|
||||
/* HMAC key */
|
||||
static uint8_t csp_hmac_key[HMAC_KEY_LENGTH];
|
||||
|
||||
/* HMAC state structure */
|
||||
typedef struct {
|
||||
csp_sha1_state md;
|
||||
uint8_t key[SHA1_BLOCKSIZE];
|
||||
} hmac_state;
|
||||
|
||||
static int csp_hmac_init(hmac_state * hmac, const uint8_t * key, uint32_t keylen) {
|
||||
uint32_t i;
|
||||
uint8_t buf[SHA1_BLOCKSIZE];
|
||||
|
||||
/* NULL pointer and key check */
|
||||
if (!hmac || !key || keylen < 1)
|
||||
return CSP_ERR_INVAL;
|
||||
|
||||
/* Make sure we have a large enough key */
|
||||
if(keylen > SHA1_BLOCKSIZE) {
|
||||
csp_sha1_memory(key, keylen, hmac->key);
|
||||
if(SHA1_DIGESTSIZE < SHA1_BLOCKSIZE)
|
||||
memset((hmac->key) + SHA1_DIGESTSIZE, 0, (size_t)(SHA1_BLOCKSIZE - SHA1_DIGESTSIZE));
|
||||
} else {
|
||||
memcpy(hmac->key, key, (size_t)keylen);
|
||||
if(keylen < SHA1_BLOCKSIZE)
|
||||
memset((hmac->key) + keylen, 0, (size_t)(SHA1_BLOCKSIZE - keylen));
|
||||
}
|
||||
|
||||
/* Create the initial vector */
|
||||
for(i = 0; i < SHA1_BLOCKSIZE; i++)
|
||||
buf[i] = hmac->key[i] ^ 0x36;
|
||||
|
||||
/* Prepend to the hash data */
|
||||
csp_sha1_init(&hmac->md);
|
||||
csp_sha1_process(&hmac->md, buf, SHA1_BLOCKSIZE);
|
||||
|
||||
return CSP_ERR_NONE;
|
||||
}
|
||||
|
||||
static int csp_hmac_process(hmac_state * hmac, const uint8_t * in, uint32_t inlen) {
|
||||
|
||||
/* NULL pointer check */
|
||||
if (!hmac || !in)
|
||||
return CSP_ERR_INVAL;
|
||||
|
||||
/* Process data */
|
||||
csp_sha1_process(&hmac->md, in, inlen);
|
||||
|
||||
return CSP_ERR_NONE;
|
||||
}
|
||||
|
||||
static int csp_hmac_done(hmac_state * hmac, uint8_t * out) {
|
||||
|
||||
uint32_t i;
|
||||
uint8_t buf[SHA1_BLOCKSIZE];
|
||||
uint8_t isha[SHA1_DIGESTSIZE];
|
||||
|
||||
if (!hmac || !out)
|
||||
return CSP_ERR_INVAL;
|
||||
|
||||
/* Get the hash of the first HMAC vector plus the data */
|
||||
csp_sha1_done(&hmac->md, isha);
|
||||
|
||||
/* Create the second HMAC vector vector */
|
||||
for(i = 0; i < SHA1_BLOCKSIZE; i++)
|
||||
buf[i] = hmac->key[i] ^ 0x5C;
|
||||
|
||||
/* Now calculate the outer hash */
|
||||
csp_sha1_init(&hmac->md);
|
||||
csp_sha1_process(&hmac->md, buf, SHA1_BLOCKSIZE);
|
||||
csp_sha1_process(&hmac->md, isha, SHA1_DIGESTSIZE);
|
||||
csp_sha1_done(&hmac->md, buf);
|
||||
|
||||
/* Copy to output */
|
||||
for (i = 0; i < SHA1_DIGESTSIZE; i++)
|
||||
out[i] = buf[i];
|
||||
|
||||
return CSP_ERR_NONE;
|
||||
}
|
||||
|
||||
int csp_hmac_memory(const uint8_t * key, uint32_t keylen, const uint8_t * data, uint32_t datalen, uint8_t * hmac) {
|
||||
hmac_state state;
|
||||
|
||||
/* NULL pointer check */
|
||||
if (!key || !data || !hmac)
|
||||
return CSP_ERR_INVAL;
|
||||
|
||||
/* Init HMAC state */
|
||||
if (csp_hmac_init(&state, key, keylen) != 0)
|
||||
return CSP_ERR_INVAL;
|
||||
|
||||
/* Process data */
|
||||
if (csp_hmac_process(&state, data, datalen) != 0)
|
||||
return CSP_ERR_INVAL;
|
||||
|
||||
/* Output HMAC */
|
||||
if (csp_hmac_done(&state, hmac) != 0)
|
||||
return CSP_ERR_INVAL;
|
||||
|
||||
return CSP_ERR_NONE;
|
||||
}
|
||||
|
||||
int csp_hmac_set_key(char * key, uint32_t keylen) {
|
||||
|
||||
/* Use SHA1 as KDF */
|
||||
uint8_t hash[SHA1_DIGESTSIZE];
|
||||
csp_sha1_memory((uint8_t *)key, keylen, hash);
|
||||
|
||||
/* Copy key */
|
||||
memcpy(csp_hmac_key, hash, HMAC_KEY_LENGTH);
|
||||
|
||||
return CSP_ERR_NONE;
|
||||
|
||||
}
|
||||
|
||||
int csp_hmac_append(csp_packet_t * packet, bool include_header) {
|
||||
|
||||
/* NULL pointer check */
|
||||
if (packet == NULL)
|
||||
return CSP_ERR_INVAL;
|
||||
|
||||
uint8_t hmac[SHA1_DIGESTSIZE];
|
||||
|
||||
/* Calculate HMAC */
|
||||
if (include_header) {
|
||||
csp_hmac_memory(csp_hmac_key, HMAC_KEY_LENGTH, (uint8_t *) &packet->id, packet->length + sizeof(packet->id), hmac);
|
||||
} else {
|
||||
csp_hmac_memory(csp_hmac_key, HMAC_KEY_LENGTH, packet->data, packet->length, hmac);
|
||||
}
|
||||
|
||||
/* Truncate hash and copy to packet */
|
||||
memcpy(&packet->data[packet->length], hmac, CSP_HMAC_LENGTH);
|
||||
packet->length += CSP_HMAC_LENGTH;
|
||||
|
||||
return CSP_ERR_NONE;
|
||||
|
||||
}
|
||||
|
||||
int csp_hmac_verify(csp_packet_t * packet, bool include_header) {
|
||||
|
||||
/* NULL pointer check */
|
||||
if (packet == NULL)
|
||||
return CSP_ERR_INVAL;
|
||||
|
||||
uint8_t hmac[SHA1_DIGESTSIZE];
|
||||
|
||||
/* Calculate HMAC */
|
||||
if (include_header) {
|
||||
csp_hmac_memory(csp_hmac_key, HMAC_KEY_LENGTH, (uint8_t *) &packet->id, packet->length + sizeof(packet->id) - CSP_HMAC_LENGTH, hmac);
|
||||
} else {
|
||||
csp_hmac_memory(csp_hmac_key, HMAC_KEY_LENGTH, packet->data, packet->length - CSP_HMAC_LENGTH, hmac);
|
||||
}
|
||||
|
||||
/* Compare calculated HMAC with packet header */
|
||||
if (memcmp(&packet->data[packet->length] - CSP_HMAC_LENGTH, hmac, CSP_HMAC_LENGTH) != 0) {
|
||||
/* HMAC failed */
|
||||
return CSP_ERR_HMAC;
|
||||
} else {
|
||||
/* Strip HMAC */
|
||||
packet->length -= CSP_HMAC_LENGTH;
|
||||
return CSP_ERR_NONE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // CSP_USE_HMAC
|
217
thirdparty/libcsp/src/crypto/csp_sha1.c
vendored
Normal file
217
thirdparty/libcsp/src/crypto/csp_sha1.c
vendored
Normal file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
|
||||
Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com)
|
||||
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* Code originally from Python's SHA1 Module, who based it on libtom.org */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
/* CSP includes */
|
||||
#include <csp/csp.h>
|
||||
|
||||
#include <csp/crypto/csp_sha1.h>
|
||||
|
||||
#if defined(CSP_USE_HMAC) || defined(CSP_USE_XTEA)
|
||||
|
||||
/* Rotate left macro */
|
||||
#define ROL(x,y) (((x) << (y)) | ((x) >> (32-y)))
|
||||
|
||||
/* Endian Neutral macros that work on all platforms */
|
||||
#define STORE32H(x, y) do { (y)[0] = (uint8_t)(((x) >> 24) & 0xff); \
|
||||
(y)[1] = (uint8_t)(((x) >> 16) & 0xff); \
|
||||
(y)[2] = (uint8_t)(((x) >> 8) & 0xff); \
|
||||
(y)[3] = (uint8_t)(((x) >> 0) & 0xff); } while (0)
|
||||
|
||||
#define LOAD32H(x, y) do { (x) = ((uint32_t)((y)[0] & 0xff) << 24) | \
|
||||
((uint32_t)((y)[1] & 0xff) << 16) | \
|
||||
((uint32_t)((y)[2] & 0xff) << 8) | \
|
||||
((uint32_t)((y)[3] & 0xff) << 0); } while (0)
|
||||
|
||||
#define STORE64H(x, y) do { (y)[0] = (uint8_t)(((x) >> 56) & 0xff); \
|
||||
(y)[1] = (uint8_t)(((x) >> 48) & 0xff); \
|
||||
(y)[2] = (uint8_t)(((x) >> 40) & 0xff); \
|
||||
(y)[3] = (uint8_t)(((x) >> 32) & 0xff); \
|
||||
(y)[4] = (uint8_t)(((x) >> 24) & 0xff); \
|
||||
(y)[5] = (uint8_t)(((x) >> 16) & 0xff); \
|
||||
(y)[6] = (uint8_t)(((x) >> 8) & 0xff); \
|
||||
(y)[7] = (uint8_t)(((x) >> 0) & 0xff); } while (0)
|
||||
|
||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
|
||||
/* SHA1 macros */
|
||||
#define F0(x,y,z) (z ^ (x & (y ^ z)))
|
||||
#define F1(x,y,z) (x ^ y ^ z)
|
||||
#define F2(x,y,z) ((x & y) | (z & (x | y)))
|
||||
#define F3(x,y,z) (x ^ y ^ z)
|
||||
|
||||
#define FF_0(a, b, c, d, e, i) do {e = (ROL(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROL(b, 30);} while (0)
|
||||
#define FF_1(a, b, c, d, e, i) do {e = (ROL(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROL(b, 30);} while (0)
|
||||
#define FF_2(a, b, c, d, e, i) do {e = (ROL(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROL(b, 30);} while (0)
|
||||
#define FF_3(a, b, c, d, e, i) do {e = (ROL(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROL(b, 30);} while (0)
|
||||
|
||||
static void csp_sha1_compress(csp_sha1_state * sha1, const uint8_t * buf) {
|
||||
|
||||
uint32_t a, b, c, d, e, W[80], i;
|
||||
|
||||
/* Copy the state into 512-bits into W[0..15] */
|
||||
for (i = 0; i < 16; i++)
|
||||
LOAD32H(W[i], buf + (4*i));
|
||||
|
||||
/* Copy state */
|
||||
a = sha1->state[0];
|
||||
b = sha1->state[1];
|
||||
c = sha1->state[2];
|
||||
d = sha1->state[3];
|
||||
e = sha1->state[4];
|
||||
|
||||
/* Expand it */
|
||||
for (i = 16; i < 80; i++)
|
||||
W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
|
||||
|
||||
/* Compress */
|
||||
i = 0;
|
||||
|
||||
/* Round one */
|
||||
for (; i < 20;) {
|
||||
FF_0(a, b, c, d, e, i++);
|
||||
FF_0(e, a, b, c, d, i++);
|
||||
FF_0(d, e, a, b, c, i++);
|
||||
FF_0(c, d, e, a, b, i++);
|
||||
FF_0(b, c, d, e, a, i++);
|
||||
}
|
||||
|
||||
/* Round two */
|
||||
for (; i < 40;) {
|
||||
FF_1(a, b, c, d, e, i++);
|
||||
FF_1(e, a, b, c, d, i++);
|
||||
FF_1(d, e, a, b, c, i++);
|
||||
FF_1(c, d, e, a, b, i++);
|
||||
FF_1(b, c, d, e, a, i++);
|
||||
}
|
||||
|
||||
/* Round three */
|
||||
for (; i < 60;) {
|
||||
FF_2(a, b, c, d, e, i++);
|
||||
FF_2(e, a, b, c, d, i++);
|
||||
FF_2(d, e, a, b, c, i++);
|
||||
FF_2(c, d, e, a, b, i++);
|
||||
FF_2(b, c, d, e, a, i++);
|
||||
}
|
||||
|
||||
/* Round four */
|
||||
for (; i < 80;) {
|
||||
FF_3(a, b, c, d, e, i++);
|
||||
FF_3(e, a, b, c, d, i++);
|
||||
FF_3(d, e, a, b, c, i++);
|
||||
FF_3(c, d, e, a, b, i++);
|
||||
FF_3(b, c, d, e, a, i++);
|
||||
}
|
||||
|
||||
/* Store */
|
||||
sha1->state[0] += a;
|
||||
sha1->state[1] += b;
|
||||
sha1->state[2] += c;
|
||||
sha1->state[3] += d;
|
||||
sha1->state[4] += e;
|
||||
|
||||
}
|
||||
|
||||
void csp_sha1_init(csp_sha1_state * sha1) {
|
||||
|
||||
sha1->state[0] = 0x67452301UL;
|
||||
sha1->state[1] = 0xefcdab89UL;
|
||||
sha1->state[2] = 0x98badcfeUL;
|
||||
sha1->state[3] = 0x10325476UL;
|
||||
sha1->state[4] = 0xc3d2e1f0UL;
|
||||
sha1->curlen = 0;
|
||||
sha1->length = 0;
|
||||
|
||||
}
|
||||
|
||||
void csp_sha1_process(csp_sha1_state * sha1, const uint8_t * in, uint32_t inlen) {
|
||||
|
||||
uint32_t n;
|
||||
while (inlen > 0) {
|
||||
if (sha1->curlen == 0 && inlen >= SHA1_BLOCKSIZE) {
|
||||
csp_sha1_compress(sha1, in);
|
||||
sha1->length += SHA1_BLOCKSIZE * 8;
|
||||
in += SHA1_BLOCKSIZE;
|
||||
inlen -= SHA1_BLOCKSIZE;
|
||||
} else {
|
||||
n = MIN(inlen, (SHA1_BLOCKSIZE - sha1->curlen));
|
||||
memcpy(sha1->buf + sha1->curlen, in, (size_t)n);
|
||||
sha1->curlen += n;
|
||||
in += n;
|
||||
inlen -= n;
|
||||
if (sha1->curlen == SHA1_BLOCKSIZE) {
|
||||
csp_sha1_compress(sha1, sha1->buf);
|
||||
sha1->length += 8*SHA1_BLOCKSIZE;
|
||||
sha1->curlen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void csp_sha1_done(csp_sha1_state * sha1, uint8_t * out) {
|
||||
|
||||
uint32_t i;
|
||||
|
||||
/* Increase the length of the message */
|
||||
sha1->length += sha1->curlen * 8;
|
||||
|
||||
/* Append the '1' bit */
|
||||
sha1->buf[sha1->curlen++] = 0x80;
|
||||
|
||||
/* If the length is currently above 56 bytes we append zeros
|
||||
* then compress. Then we can fall back to padding zeros and length
|
||||
* encoding like normal.
|
||||
*/
|
||||
if (sha1->curlen > 56) {
|
||||
while (sha1->curlen < 64)
|
||||
sha1->buf[sha1->curlen++] = 0;
|
||||
csp_sha1_compress(sha1, sha1->buf);
|
||||
sha1->curlen = 0;
|
||||
}
|
||||
|
||||
/* Pad up to 56 bytes of zeroes */
|
||||
while (sha1->curlen < 56)
|
||||
sha1->buf[sha1->curlen++] = 0;
|
||||
|
||||
/* Store length */
|
||||
STORE64H(sha1->length, sha1->buf + 56);
|
||||
csp_sha1_compress(sha1, sha1->buf);
|
||||
|
||||
/* Copy output */
|
||||
for (i = 0; i < 5; i++)
|
||||
STORE32H(sha1->state[i], out + (4 * i));
|
||||
|
||||
}
|
||||
|
||||
void csp_sha1_memory(const uint8_t * msg, uint32_t len, uint8_t * hash) {
|
||||
|
||||
csp_sha1_state md;
|
||||
csp_sha1_init(&md);
|
||||
csp_sha1_process(&md, msg, len);
|
||||
csp_sha1_done(&md, hash);
|
||||
|
||||
}
|
||||
|
||||
#endif // CSP_USE_HMAC
|
134
thirdparty/libcsp/src/crypto/csp_xtea.c
vendored
Normal file
134
thirdparty/libcsp/src/crypto/csp_xtea.c
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
Cubesat Space Protocol - A small network-layer protocol designed for Cubesats
|
||||
Copyright (C) 2012 GomSpace ApS (http://www.gomspace.com)
|
||||
Copyright (C) 2012 AAUSAT3 Project (http://aausat3.space.aau.dk)
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* Simple implementation of XTEA in CTR mode */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
/* CSP includes */
|
||||
#include <csp/csp.h>
|
||||
#include <csp/csp_endian.h>
|
||||
#include <csp/crypto/csp_sha1.h>
|
||||
#include <csp/crypto/csp_xtea.h>
|
||||
|
||||
#ifdef CSP_USE_XTEA
|
||||
|
||||
#define XTEA_BLOCKSIZE 8
|
||||
#define XTEA_ROUNDS 32
|
||||
#define XTEA_KEY_LENGTH 16
|
||||
|
||||
/* XTEA key */
|
||||
static uint32_t csp_xtea_key[XTEA_KEY_LENGTH/sizeof(uint32_t)] __attribute__ ((aligned(sizeof(uint32_t))));
|
||||
|
||||
#define STORE32L(x, y) do { (y)[3] = (uint8_t)(((x) >> 24) & 0xff); \
|
||||
(y)[2] = (uint8_t)(((x) >> 16) & 0xff); \
|
||||
(y)[1] = (uint8_t)(((x) >> 8) & 0xff); \
|
||||
(y)[0] = (uint8_t)(((x) >> 0) & 0xff); } while (0)
|
||||
|
||||
#define LOAD32L(x, y) do { (x) = ((uint32_t)((y)[3] & 0xff) << 24) | \
|
||||
((uint32_t)((y)[2] & 0xff) << 16) | \
|
||||
((uint32_t)((y)[1] & 0xff) << 8) | \
|
||||
((uint32_t)((y)[0] & 0xff) << 0); } while (0)
|
||||
|
||||
/* This function takes 64 bits of data in block and the 128 bits key in key */
|
||||
static inline void csp_xtea_encrypt_block(uint8_t *block, uint8_t const *key) {
|
||||
|
||||
uint32_t i, v0, v1, delta = 0x9E3779B9, sum = 0, k[4];
|
||||
|
||||
LOAD32L(k[0], &key[0]);
|
||||
LOAD32L(k[1], &key[4]);
|
||||
LOAD32L(k[2], &key[8]);
|
||||
LOAD32L(k[3], &key[12]);
|
||||
|
||||
LOAD32L(v0, &block[0]);
|
||||
LOAD32L(v1, &block[4]);
|
||||
|
||||
for (i = 0; i < XTEA_ROUNDS; i++) {
|
||||
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
|
||||
sum += delta;
|
||||
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum >> 11) & 3]);
|
||||
}
|
||||
|
||||
STORE32L(v0, &block[0]);
|
||||
STORE32L(v1, &block[4]);
|
||||
|
||||
}
|
||||
|
||||
static inline void csp_xtea_xor_byte(uint8_t * dst, uint8_t * src, uint32_t len) {
|
||||
|
||||
unsigned int i;
|
||||
for (i = 0; i < len; i++)
|
||||
dst[i] ^= src[i];
|
||||
|
||||
}
|
||||
|
||||
int csp_xtea_set_key(char * key, uint32_t keylen) {
|
||||
|
||||
/* Use SHA1 as KDF */
|
||||
uint8_t hash[SHA1_DIGESTSIZE];
|
||||
csp_sha1_memory((uint8_t *)key, keylen, hash);
|
||||
|
||||
/* Copy key */
|
||||
memcpy(csp_xtea_key, hash, XTEA_KEY_LENGTH);
|
||||
|
||||
return CSP_ERR_NONE;
|
||||
|
||||
}
|
||||
|
||||
int csp_xtea_encrypt(uint8_t * plain, const uint32_t len, uint32_t iv[2]) {
|
||||
|
||||
unsigned int i;
|
||||
uint32_t stream[2];
|
||||
|
||||
uint32_t blocks = (len + XTEA_BLOCKSIZE - 1)/ XTEA_BLOCKSIZE;
|
||||
uint32_t remain;
|
||||
|
||||
/* Initialize stream */
|
||||
stream[0] = csp_htobe32(iv[0]);
|
||||
stream[1] = csp_htobe32(iv[1]);
|
||||
|
||||
for (i = 0; i < blocks; i++) {
|
||||
/* Create stream */
|
||||
csp_xtea_encrypt_block((uint8_t *)stream, (uint8_t *)csp_xtea_key);
|
||||
|
||||
/* Calculate remaining bytes */
|
||||
remain = len - i * XTEA_BLOCKSIZE;
|
||||
|
||||
/* XOR plain text with stream to generate cipher text */
|
||||
csp_xtea_xor_byte(&plain[len - remain], (uint8_t *)stream, remain < XTEA_BLOCKSIZE ? remain : XTEA_BLOCKSIZE);
|
||||
|
||||
/* Increment counter */
|
||||
stream[0] = csp_htobe32(iv[0]);
|
||||
stream[1] = csp_htobe32(iv[1]++);
|
||||
}
|
||||
|
||||
return CSP_ERR_NONE;
|
||||
|
||||
}
|
||||
|
||||
int csp_xtea_decrypt(uint8_t * cipher, const uint32_t len, uint32_t iv[2]) {
|
||||
|
||||
/* Since we use counter mode, we can reuse the encryption function */
|
||||
return csp_xtea_encrypt(cipher, len, iv);
|
||||
|
||||
}
|
||||
|
||||
#endif // CSP_USE_XTEA
|
Reference in New Issue
Block a user