diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2015-04-13 12:57:12 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2015-04-13 12:57:12 +0200 |
commit | 909dbe5334d54a5538128ebf18391608315c2f9a (patch) | |
tree | ded97d91bba0ba00dabef434dd98611ea5cd6e15 /common | |
parent | 881d2e4ac607d8545dd2e62892436c759b8c0958 (diff) | |
parent | 238ffb68f62525f12ef1af1ebe316360634ec529 (diff) | |
download | barebox-909dbe5334d54a5538128ebf18391608315c2f9a.tar.gz barebox-909dbe5334d54a5538128ebf18391608315c2f9a.tar.xz |
Merge branch 'for-next/crypto'
Diffstat (limited to 'common')
-rw-r--r-- | common/Kconfig | 8 | ||||
-rw-r--r-- | common/Makefile | 1 | ||||
-rw-r--r-- | common/command.c | 2 | ||||
-rw-r--r-- | common/digest.c | 174 | ||||
-rw-r--r-- | common/password.c | 99 |
5 files changed, 79 insertions, 205 deletions
diff --git a/common/Kconfig b/common/Kconfig index b68371358d..242f1e4047 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -449,6 +449,14 @@ config PASSWD_SUM_SHA256 bool "SHA256" select SHA256 +config PASSWD_SUM_SHA512 + bool "SHA512" + select SHA512 + +config PASSWD_CRYPTO_PBKDF2 + bool "PBKDF2" + select CRYPTO_PBKDF2 + endchoice endif diff --git a/common/Makefile b/common/Makefile index ee5dca7023..6bfbfb4745 100644 --- a/common/Makefile +++ b/common/Makefile @@ -20,7 +20,6 @@ obj-$(CONFIG_CMD_MEMTEST) += memtest.o obj-$(CONFIG_COMMAND_SUPPORT) += command.o obj-$(CONFIG_CONSOLE_FULL) += console.o obj-$(CONFIG_CONSOLE_SIMPLE) += console_simple.o -obj-$(CONFIG_DIGEST) += digest.o obj-$(CONFIG_DDR_SPD) += ddr_spd.o obj-$(CONFIG_ENV_HANDLING) += environment.o obj-$(CONFIG_ENVIRONMENT_VARIABLES) += env.o diff --git a/common/command.c b/common/command.c index 61191c2d62..dc2cb88eaf 100644 --- a/common/command.c +++ b/common/command.c @@ -47,6 +47,8 @@ void barebox_cmd_usage(struct command *cmdtp) puts(cmdtp->help); putchar('\n'); } + if (cmdtp->usage) + cmdtp->usage(); #endif } EXPORT_SYMBOL(barebox_cmd_usage); diff --git a/common/digest.c b/common/digest.c deleted file mode 100644 index ae414ba5d5..0000000000 --- a/common/digest.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * (C) Copyright 2008-2010 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program 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; version 2 of - * the License. - * - * 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. - * - */ - -#include <common.h> -#include <digest.h> -#include <malloc.h> -#include <fs.h> -#include <fcntl.h> -#include <linux/stat.h> -#include <errno.h> -#include <module.h> -#include <linux/err.h> - -static LIST_HEAD(digests); - -static int dummy_init(struct digest *d) -{ - return 0; -} - -int digest_register(struct digest *d) -{ - if (!d || !d->name || !d->update || !d->final || d->length < 1) - return -EINVAL; - - if (!d->init) - d->init = dummy_init; - - if (digest_get_by_name(d->name)) - return -EEXIST; - - list_add_tail(&d->list, &digests); - - return 0; -} -EXPORT_SYMBOL(digest_register); - -void digest_unregister(struct digest *d) -{ - if (!d) - return; - - list_del(&d->list); -} -EXPORT_SYMBOL(digest_unregister); - -struct digest* digest_get_by_name(char* name) -{ - struct digest* d; - - if (!name) - return NULL; - - list_for_each_entry(d, &digests, list) { - if(strcmp(d->name, name) == 0) - return d; - } - - return NULL; -} -EXPORT_SYMBOL_GPL(digest_get_by_name); - -int digest_file_window(struct digest *d, char *filename, - unsigned char *hash, - ulong start, ulong size) -{ - ulong len = 0; - int fd, now, ret = 0; - unsigned char *buf; - int flags = 0; - - d->init(d); - - fd = open(filename, O_RDONLY); - if (fd < 0) { - perror(filename); - return fd; - } - - buf = memmap(fd, PROT_READ); - if (buf == (void *)-1) { - buf = xmalloc(4096); - flags = 1; - } - - if (start > 0) { - if (flags) { - ret = lseek(fd, start, SEEK_SET); - if (ret == -1) { - perror("lseek"); - goto out; - } - } else { - buf += start; - } - } - - while (size) { - now = min((ulong)4096, size); - if (flags) { - now = read(fd, buf, now); - if (now < 0) { - ret = now; - perror("read"); - goto out_free; - } - if (!now) - break; - } - - if (ctrlc()) { - ret = -EINTR; - goto out_free; - } - - d->update(d, buf, now); - size -= now; - len += now; - } - - d->final(d, hash); - -out_free: - if (flags) - free(buf); -out: - close(fd); - - return ret; -} -EXPORT_SYMBOL_GPL(digest_file_window); - -int digest_file(struct digest *d, char *filename, - unsigned char *hash) -{ - struct stat st; - int ret; - - ret = stat(filename, &st); - - if (ret < 0) - return ret; - - return digest_file_window(d, filename, hash, 0, st.st_size); -} -EXPORT_SYMBOL_GPL(digest_file); - -int digest_file_by_name(char *algo, char *filename, - unsigned char *hash) -{ - struct digest *d; - - d = digest_get_by_name(algo); - if (!d) - return -EIO; - - return digest_file(d, filename, hash); -} -EXPORT_SYMBOL_GPL(digest_file_by_name); diff --git a/common/password.c b/common/password.c index 111c139286..c8454228d0 100644 --- a/common/password.c +++ b/common/password.c @@ -25,7 +25,9 @@ #include <malloc.h> #include <xfuncs.h> #include <clock.h> +#include <stdlib.h> #include <generated/passwd.h> +#include <crypto/pbkdf2.h> #if defined(CONFIG_PASSWD_SUM_MD5) #define PASSWD_SUM "md5" @@ -33,8 +35,16 @@ #define PASSWD_SUM "sha1" #elif defined(CONFIG_PASSWD_SUM_SHA256) #define PASSWD_SUM "sha256" +#elif defined(CONFIG_PASSWD_SUM_SHA512) +#define PASSWD_SUM "sha512" +#else +#define PASSWD_SUM NULL #endif +#define PBKDF2_SALT_LEN 32 +#define PBKDF2_LENGTH 64 +#define PBKDF2_COUNT 10000 + int password(unsigned char *passwd, size_t length, int flags, int timeout) { unsigned char *buf = passwd; @@ -275,46 +285,59 @@ EXPORT_SYMBOL(write_env_passwd); static int __check_passwd(unsigned char* passwd, size_t length, int std) { - struct digest *d; + struct digest *d = NULL; unsigned char *passwd1_sum; unsigned char *passwd2_sum; int ret = 0; + int hash_len; - d = digest_get_by_name(PASSWD_SUM); + if (IS_ENABLED(CONFIG_PASSWD_CRYPTO_PBKDF2)) { + hash_len = PBKDF2_LENGTH; + } else { + d = digest_alloc(PASSWD_SUM); - passwd1_sum = calloc(d->length, sizeof(unsigned char)); + hash_len = digest_length(d); + } + passwd1_sum = calloc(hash_len * 2, sizeof(unsigned char)); if (!passwd1_sum) return -ENOMEM; - passwd2_sum = calloc(d->length, sizeof(unsigned char)); + passwd2_sum = passwd1_sum + hash_len; - if (!passwd2_sum) { - ret = -ENOMEM; - goto err1; - } + if (std) + ret = read_env_passwd(passwd2_sum, hash_len); + else + ret = read_default_passwd(passwd2_sum, hash_len); - d->init(d); + if (ret < 0) + goto err; - d->update(d, passwd, length); + if (IS_ENABLED(CONFIG_PASSWD_CRYPTO_PBKDF2)) { + char *key = passwd2_sum + PBKDF2_SALT_LEN; + char *salt = passwd2_sum; + int keylen = PBKDF2_LENGTH - PBKDF2_SALT_LEN; - d->final(d, passwd1_sum); + ret = pkcs5_pbkdf2_hmac_sha1(passwd, length, salt, + PBKDF2_SALT_LEN, PBKDF2_COUNT, keylen, passwd1_sum); + if (ret) + goto err; - if (std) - ret = read_env_passwd(passwd2_sum, d->length); - else - ret = read_default_passwd(passwd2_sum, d->length); + if (strncmp(passwd1_sum, key, keylen) == 0) + ret = 1; + } else { + ret = digest_digest(d, passwd, length, passwd1_sum); - if (ret < 0) - goto err2; + if (ret) + goto err; - if (strncmp(passwd1_sum, passwd2_sum, d->length) == 0) - ret = 1; + if (strncmp(passwd1_sum, passwd2_sum, hash_len) == 0) + ret = 1; + } -err2: - free(passwd2_sum); -err1: +err: free(passwd1_sum); + digest_free(d); return ret; } @@ -343,25 +366,41 @@ int check_passwd(unsigned char* passwd, size_t length) int set_env_passwd(unsigned char* passwd, size_t length) { - struct digest *d; + struct digest *d = NULL; unsigned char *passwd_sum; - int ret; + int ret, hash_len; - d = digest_get_by_name(PASSWD_SUM); + if (IS_ENABLED(CONFIG_PASSWD_CRYPTO_PBKDF2)) { + hash_len = PBKDF2_LENGTH; + } else { + d = digest_alloc(PASSWD_SUM); - passwd_sum = calloc(d->length, sizeof(unsigned char)); + hash_len = digest_length(d); + } + passwd_sum = calloc(hash_len, sizeof(unsigned char)); if (!passwd_sum) return -ENOMEM; - d->init(d); + if (IS_ENABLED(CONFIG_PASSWD_CRYPTO_PBKDF2)) { + char *key = passwd_sum + PBKDF2_SALT_LEN; + char *salt = passwd_sum; + int keylen = PBKDF2_LENGTH - PBKDF2_SALT_LEN; - d->update(d, passwd, length); + get_random_bytes(passwd_sum, PBKDF2_SALT_LEN); - d->final(d, passwd_sum); + ret = pkcs5_pbkdf2_hmac_sha1(passwd, length, salt, + PBKDF2_SALT_LEN, PBKDF2_COUNT, keylen, key); + } else { + ret = digest_digest(d, passwd, length, passwd_sum); + } + if (ret) + goto err; - ret = write_env_passwd(passwd_sum, d->length); + ret = write_env_passwd(passwd_sum, hash_len); +err: + digest_free(d); free(passwd_sum); return ret; |