From aa13bdb17609cccbd47c29103847d813015ffbd6 Mon Sep 17 00:00:00 2001 From: rasky Date: Fri, 24 Sep 2010 16:26:32 +0000 Subject: [PATCH] SEC: Add utilities module. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@4306 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/sec/util.c | 57 ++++++++++++++++++++++++++++ bertos/sec/util.h | 95 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 bertos/sec/util.c create mode 100644 bertos/sec/util.h diff --git a/bertos/sec/util.c b/bertos/sec/util.c new file mode 100644 index 00000000..b5982b38 --- /dev/null +++ b/bertos/sec/util.c @@ -0,0 +1,57 @@ +/** + * \file + * + * + * \brief Generic utilities. + * \author Giovanni Bajo + * + */ + +#include "util.h" +#include +#include +#include + +// FIXME: this macros should be generated by the wizard +#define BERTOS_PROJECT_NAME "bertos_project" + +#define SALT (BERTOS_PROJECT_NAME "P2K_SALT") + +void password2key(const char *pwd, size_t pwd_len, + uint8_t *key, size_t key_len) +{ + Kdf *kdf = PBKDF2_stackinit(HMAC_stackinit(SHA1_stackinit())); + + kdf_begin(kdf, pwd, pwd_len, (uint8_t*)SALT, sizeof(SALT)); + kdf_read(kdf, key, key_len); + + // FIXME: how to purge the stack? +} diff --git a/bertos/sec/util.h b/bertos/sec/util.h new file mode 100644 index 00000000..e8e0aa2f --- /dev/null +++ b/bertos/sec/util.h @@ -0,0 +1,95 @@ +#ifndef SEC_UTIL_H +#define SEC_UTIL_H + +#include +#include + +/** + * Purge local variables, by zeroing them. + * + * This can be used to clear stack from intermediate results in crypto + * calculations that might somehow be leaked. + */ +#define PURGE(x) \ + memset(&x, 0, sizeof(x)) + +/** + * Convert a generic "password" (low-diffused) to a generic "key" + * (high-diffused). + * + * In common terminology, a "password" is a key with weak cryptographic + * characteristics, such as commonly used password input by an user, + * which are usually short and use only a few different characters from + * the 0-255 byte range. + * + * This function derives a strong key from the password using a one-way + * process. + * + * \note Uses PBKDF2 as key-derivation function, with a fixed salt that + * changes for each Bertos project. + */ +void password2key(const char *pwd, size_t pwd_len, + uint8_t *key, size_t key_len); + +/** + * Perform a bitwise xor between \a in and \a inout, and store + * the result into \a inout. + */ +INLINE void xor_block(uint8_t *out, const uint8_t *in1, const uint8_t* in2, size_t len); + +/** + * Perform a bitwise xor over \a inout with constant \a k. + */ +INLINE void xor_block_const(uint8_t *out, const uint8_t *in, uint8_t k, size_t len); + + +// FIXME: provide non-32bit fallback +// FIXME: proper ifdef conditional +#if 1 // 32-bit optimized versions + +// FIXME: this code is currently buggy because it ignores alignment issues. +INLINE void xor_block(uint8_t *out, const uint8_t *in1, const uint8_t* in2, size_t len) +{ + ASSERT(((size_t)in1 % 4) == 0); + ASSERT(((size_t)in2 % 4) == 0); + ASSERT(((size_t)out % 4) == 0); + + const uint32_t *ibuf1 = (const uint32_t *)in1; + const uint32_t *ibuf2 = (const uint32_t *)in2; + uint32_t *obuf = (uint32_t *)out; + size_t rem = (len & 3); + + len /= 4; + while (len--) + *obuf++ = *ibuf1++ ^ *ibuf2++; + + in1 = (const uint8_t*)ibuf1; + in2 = (const uint8_t*)ibuf2; + out = (uint8_t*)obuf; + while (rem--) + *out++ = *in1++ ^ *in2++; +} + +INLINE void xor_block_const(uint8_t *out, const uint8_t *in, uint8_t k, size_t len) +{ + ASSERT(((size_t)in % 4) == 0); + ASSERT(((size_t)out % 4) == 0); + + uint32_t k32 = k | ((uint32_t)k<<8) | ((uint32_t)k<<16) | ((uint32_t)k<<24); + const uint32_t *ibuf = (const uint32_t *)in; + uint32_t *obuf = (uint32_t *)out; + size_t rem = (len & 3); + + len /= 4; + while (len--) + *obuf++ = *ibuf++ ^ k32; + + in = (const uint8_t*)ibuf; + out = (uint8_t*)obuf; + while (rem--) + *out++ = *in++ ^ k; +} + +#endif + +#endif /* SEC_UTIL_H */ -- 2.25.1