--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2010 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Generic utilities.
+ * \author Giovanni Bajo <rasky@develer.com>
+ *
+ */
+
+#include "util.h"
+#include <sec/kdf/pbkdf2.h>
+#include <sec/mac/hmac.h>
+#include <sec/hash/sha1.h>
+
+// 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?
+}
--- /dev/null
+#ifndef SEC_UTIL_H
+#define SEC_UTIL_H
+
+#include <cfg/compiler.h>
+#include <cfg/debug.h>
+
+/**
+ * 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 */