aboutsummaryrefslogtreecommitdiff
path: root/ubifs-utils/mkfs.ubifs/fscrypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'ubifs-utils/mkfs.ubifs/fscrypt.c')
-rw-r--r--ubifs-utils/mkfs.ubifs/fscrypt.c282
1 files changed, 0 insertions, 282 deletions
diff --git a/ubifs-utils/mkfs.ubifs/fscrypt.c b/ubifs-utils/mkfs.ubifs/fscrypt.c
deleted file mode 100644
index b75bdf7..0000000
--- a/ubifs-utils/mkfs.ubifs/fscrypt.c
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * Copyright (C) 2017 sigma star gmbh
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * 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
- *
- * Authors: Richard Weinberger <richard@sigma-star.at>
- * David Oberhollenzer <david.oberhollenzer@sigma-star.at>
- */
-
-#define PROGRAM_NAME "mkfs.ubifs"
-#include "fscrypt.h"
-
-
-static __u8 fscrypt_masterkey[FS_MAX_KEY_SIZE];
-static struct cipher *fscrypt_cipher;
-
-
-unsigned char *calc_fscrypt_subkey(struct fscrypt_context *fctx)
-{
- int ret;
- unsigned char *new_key = xmalloc(FS_MAX_KEY_SIZE);
-
- ret = derive_key_aes(fctx->nonce, fscrypt_masterkey, fscrypt_cipher->key_length, new_key);
- if (ret < 0) {
- err_msg("derive_key_aes failed: %i\n", ret);
-
- free(new_key);
- new_key = NULL;
- }
-
- return new_key;
-}
-
-struct fscrypt_context *inherit_fscrypt_context(struct fscrypt_context *fctx)
-{
- struct fscrypt_context *new_fctx = NULL;
-
- if (fctx) {
- new_fctx = xmalloc(sizeof(*new_fctx));
- new_fctx->format = fctx->format;
- new_fctx->contents_encryption_mode = fctx->contents_encryption_mode;
- new_fctx->filenames_encryption_mode = fctx->filenames_encryption_mode;
- new_fctx->flags = fctx->flags;
- memcpy(new_fctx->master_key_descriptor, fctx->master_key_descriptor,
- FS_KEY_DESCRIPTOR_SIZE);
- RAND_bytes((void *)&new_fctx->nonce, FS_KEY_DERIVATION_NONCE_SIZE);
- }
-
- return new_fctx;
-}
-
-void free_fscrypt_context(struct fscrypt_context *fctx)
-{
- free(fctx);
-}
-
-static void print_fscrypt_master_key_descriptor(__u8 *master_key_descriptor)
-{
- int i;
-
- normsg_cont("fscrypt master key descriptor: 0x");
- for (i = 0; i < FS_KEY_DESCRIPTOR_SIZE; i++) {
- printf("%02x", master_key_descriptor[i]);
- }
- printf("\n");
-}
-
-unsigned int fscrypt_fname_encrypted_size(struct fscrypt_context *fctx,
- unsigned int ilen)
-{
- int padding;
-
- padding = 4 << (fctx->flags & FS_POLICY_FLAGS_PAD_MASK);
- ilen = max_t(unsigned int, ilen, FS_CRYPTO_BLOCK_SIZE);
- return round_up(ilen, padding);
-}
-
-int encrypt_path(void **outbuf, void *data, unsigned int data_len,
- unsigned int max_namelen, struct fscrypt_context *fctx)
-{
- void *inbuf, *crypt_key;
- unsigned int padding = 4 << (fctx->flags & FS_POLICY_FLAGS_PAD_MASK);
- unsigned int cryptlen;
- int ret;
-
- cryptlen = max_t(unsigned int, data_len, FS_CRYPTO_BLOCK_SIZE);
- cryptlen = round_up(cryptlen, padding);
- cryptlen = min(cryptlen, max_namelen);
-
- inbuf = xmalloc(cryptlen);
- /* CTS mode needs a block size aligned buffer */
- *outbuf = xmalloc(round_up(cryptlen, FS_CRYPTO_BLOCK_SIZE));
-
- memset(inbuf, 0, cryptlen);
- memcpy(inbuf, data, data_len);
-
- crypt_key = calc_fscrypt_subkey(fctx);
- if (!crypt_key) {
- free(inbuf);
- free(*outbuf);
- return err_msg("could not compute subkey");
- }
-
- ret = fscrypt_cipher->encrypt_fname(inbuf, cryptlen,
- crypt_key, *outbuf);
- if (ret < 0) {
- free(inbuf);
- free(*outbuf);
- return err_msg("could not encrypt filename");
- }
-
- free(crypt_key);
- free(inbuf);
- return cryptlen;
-}
-
-int encrypt_data_node(struct fscrypt_context *fctx, unsigned int block_no,
- struct ubifs_data_node *dn, size_t length)
-{
- void *inbuf, *outbuf, *crypt_key;
- size_t ret, pad_len = round_up(length, FS_CRYPTO_BLOCK_SIZE);
-
- dn->compr_size = cpu_to_le16(length);
-
- inbuf = xzalloc(pad_len);
- outbuf = xzalloc(pad_len);
-
- memcpy(inbuf, &dn->data, length);
-
- crypt_key = calc_fscrypt_subkey(fctx);
- if (!crypt_key) {
- free(inbuf);
- free(outbuf);
- return err_msg("could not compute subkey");
- }
-
- ret = fscrypt_cipher->encrypt_block(inbuf, pad_len,
- crypt_key, block_no,
- outbuf);
- if (ret != pad_len) {
- free(inbuf);
- free(outbuf);
- free(crypt_key);
- return err_msg("encrypt_block returned %zi "
- "instead of %zi", ret, pad_len);
- }
-
- memcpy(&dn->data, outbuf, pad_len);
-
- free(inbuf);
- free(outbuf);
- free(crypt_key);
- return pad_len;
-}
-
-static int xdigit(int x)
-{
- if (isupper(x))
- return x - 'A' + 0x0A;
- if (islower(x))
- return x - 'a' + 0x0A;
- return x - '0';
-}
-
-static int parse_key_descriptor(const char *desc, __u8 *dst)
-{
- int i, hi, lo;
-
- if (desc[0] == '0' && (desc[1] == 'x' || desc[1] == 'X'))
- desc += 2;
-
- for (i = 0; i < FS_KEY_DESCRIPTOR_SIZE; ++i) {
- if (!desc[i * 2] || !desc[i * 2 + 1]) {
- err_msg("key descriptor '%s' is too short", desc);
- return -1;
- }
- if (!isxdigit(desc[i * 2]) || !isxdigit(desc[i * 2 + 1])) {
- err_msg("invalid key descriptor '%s'", desc);
- return -1;
- }
-
- hi = xdigit(desc[i * 2]);
- lo = xdigit(desc[i * 2 + 1]);
-
- dst[i] = (hi << 4) | lo;
- }
-
- if (desc[i * 2]) {
- err_msg("key descriptor '%s' is too long", desc);
- return -1;
- }
- return 0;
-}
-
-static int load_master_key(const char *key_file, struct cipher *fsc)
-{
- int kf;
- ssize_t keysize;
-
- kf = open(key_file, O_RDONLY);
- if (kf < 0) {
- sys_errmsg("open '%s'", key_file);
- return -1;
- }
-
- keysize = read(kf, fscrypt_masterkey, FS_MAX_KEY_SIZE);
- if (keysize < 0) {
- sys_errmsg("read '%s'", key_file);
- goto fail;
- }
- if (keysize == 0) {
- err_msg("loading key from '%s': file is empty", key_file);
- goto fail;
- }
- if (keysize < fsc->key_length) {
- err_msg("key '%s' is too short (at least %u bytes required)",
- key_file, fsc->key_length);
- goto fail;
- }
-
- close(kf);
- return 0;
-fail:
- close(kf);
- return -1;
-}
-
-struct fscrypt_context *init_fscrypt_context(const char *cipher_name,
- unsigned int flags,
- const char *key_file,
- const char *key_descriptor)
-{
- __u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
- __u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE];
- struct fscrypt_context *new_fctx;
-
- fscrypt_cipher = get_cipher(cipher_name);
-
- if (!fscrypt_cipher) {
- fprintf(stderr, "Cannot find cipher '%s'\n"
- "Try `%s --help' for more information\n",
- cipher_name, PROGRAM_NAME);
- return NULL;
- }
-
- if (load_master_key(key_file, fscrypt_cipher))
- return NULL;
-
- if (!key_descriptor) {
- if (derive_key_descriptor(fscrypt_masterkey, master_key_descriptor))
- return NULL;
- print_fscrypt_master_key_descriptor(master_key_descriptor);
- } else {
- if (parse_key_descriptor(key_descriptor, master_key_descriptor))
- return NULL;
- }
-
- RAND_bytes((void *)nonce, FS_KEY_DERIVATION_NONCE_SIZE);
-
- new_fctx = xmalloc(sizeof(*new_fctx));
-
- new_fctx->format = FS_ENCRYPTION_CONTEXT_FORMAT_V1;
- new_fctx->contents_encryption_mode = fscrypt_cipher->fscrypt_block_mode;
- new_fctx->filenames_encryption_mode = fscrypt_cipher->fscrypt_fname_mode;
- new_fctx->flags = flags;
-
- memcpy(&new_fctx->nonce, nonce, FS_KEY_DERIVATION_NONCE_SIZE);
- memcpy(&new_fctx->master_key_descriptor, master_key_descriptor,
- FS_KEY_DESCRIPTOR_SIZE);
- return new_fctx;
-}