SEC: Add utilities module.
authorrasky <rasky@38d2e660-2303-0410-9eaa-f027e97ec537>
Fri, 24 Sep 2010 16:26:32 +0000 (16:26 +0000)
committerrasky <rasky@38d2e660-2303-0410-9eaa-f027e97ec537>
Fri, 24 Sep 2010 16:26:32 +0000 (16:26 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@4306 38d2e660-2303-0410-9eaa-f027e97ec537

bertos/sec/util.c [new file with mode: 0644]
bertos/sec/util.h [new file with mode: 0644]

diff --git a/bertos/sec/util.c b/bertos/sec/util.c
new file mode 100644 (file)
index 0000000..b5982b3
--- /dev/null
@@ -0,0 +1,57 @@
+/**
+ * \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?
+}
diff --git a/bertos/sec/util.h b/bertos/sec/util.h
new file mode 100644 (file)
index 0000000..e8e0aa2
--- /dev/null
@@ -0,0 +1,95 @@
+#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 */