X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fsec%2Futil.h;h=2fcf1b8f0926342ab5cabf30a80832fb83cc7538;hb=7911a6f01bc8a19f220f98e2fdc8595f65996853;hp=36ce22f883a26d5917ce23e573898fe6331a2e2d;hpb=f3a74d05913e05818c39b796968fda9277e213f9;p=bertos.git diff --git a/bertos/sec/util.h b/bertos/sec/util.h index 36ce22f8..2fcf1b8f 100644 --- a/bertos/sec/util.h +++ b/bertos/sec/util.h @@ -1,13 +1,14 @@ #ifndef SEC_UTIL_H #define SEC_UTIL_H +#include #include #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. */ @@ -17,80 +18,106 @@ /** * 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, + * 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 +INLINE void xor_block_8(uint8_t *out, + const uint8_t *in1, const uint8_t *in2, size_t len) +{ + while (len--) + *out++ = *in1++ ^ *in2++; +} -// 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) +INLINE void xor_block_const_8(uint8_t *out, + const uint8_t *in, uint8_t k, 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++; + *out++ = *in++ ^ k; +} - in1 = (const uint8_t*)ibuf1; - in2 = (const uint8_t*)ibuf2; - out = (uint8_t*)obuf; - while (rem--) +INLINE void xor_block_32(uint32_t *out, const uint32_t *in1, + const uint32_t *in2, size_t len) +{ + size_t rem = (len & (sizeof(uint32_t) - 1)); + + len /= sizeof(uint32_t); + while (len--) *out++ = *in1++ ^ *in2++; + xor_block_8((uint8_t *)out, + (const uint8_t *)in1, (const uint8_t *)in2, rem); } -INLINE void xor_block_const(uint8_t *out, const uint8_t *in, uint8_t k, size_t len) +INLINE void xor_block_const_32(uint32_t *out, const uint32_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; + uint32_t k32 = k | ((uint32_t)k << 8) | + ((uint32_t)k << 16) | ((uint32_t)k << 24); + size_t rem = (len & (sizeof(uint32_t) - 1)); + + len /= sizeof(uint32_t); while (len--) - *obuf++ = *ibuf++ ^ k32; + *out++ = *in++ ^ k32; + xor_block_const_8((uint8_t *)out, (const uint8_t *)in, k, rem); +} + +/** + * Perform a bitwise xor between \a in and \a inout, and store + * the result into \a inout. + */ +INLINE void xor_block(void *out, const void *in1, const void *in2, size_t len) +{ + if (is_aligned(out, sizeof(uint32_t)) && + is_aligned(in1, sizeof(uint32_t)) && + is_aligned(in2, sizeof(uint32_t))) + { + uint32_t *obuf = (uint32_t *)((size_t)out); + const uint32_t *ibuf1 = (const uint32_t *)((size_t)in1); + const uint32_t *ibuf2 = (const uint32_t *)((size_t)in2); + + xor_block_32(obuf, ibuf1, ibuf2, len); + } + else + { + uint8_t *obuf = (uint8_t *)((size_t)out); + const uint8_t *ibuf1 = (const uint8_t *)((size_t)in1); + const uint8_t *ibuf2 = (const uint8_t *)((size_t)in2); - in = (const uint8_t*)ibuf; - out = (uint8_t*)obuf; - while (rem--) - *out++ = *in++ ^ k; + xor_block_8(obuf, ibuf1, ibuf2, len); + } } -#endif +/** + * 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) +{ + if (is_aligned(out, sizeof(uint32_t)) && + is_aligned(in, sizeof(uint32_t))) + { + uint32_t *obuf = (uint32_t *)((size_t)out); + const uint32_t *ibuf = (const uint32_t *)((size_t)in); + + xor_block_const_32(obuf, ibuf, k, len); + } + else + { + uint8_t *obuf = (uint8_t *)((size_t)out); + const uint8_t *ibuf = (const uint8_t *)((size_t)in); + + xor_block_const_8(obuf, ibuf, k, len); + } +} #endif /* SEC_UTIL_H */