diff options
Diffstat (limited to 'xlators/encryption/crypt/src/metadata.c')
-rw-r--r-- | xlators/encryption/crypt/src/metadata.c | 875 |
1 files changed, 418 insertions, 457 deletions
diff --git a/xlators/encryption/crypt/src/metadata.c b/xlators/encryption/crypt/src/metadata.c index 96fe7d64e21..90c53a9f721 100644 --- a/xlators/encryption/crypt/src/metadata.c +++ b/xlators/encryption/crypt/src/metadata.c @@ -13,236 +13,235 @@ #include "crypt.h" #include "metadata.h" -int32_t alloc_format(crypt_local_t *local, size_t size) +int32_t +alloc_format(crypt_local_t *local, size_t size) { - if (size > 0) { - local->format = GF_CALLOC(1, size, gf_crypt_mt_mtd); - if (!local->format) - return ENOMEM; - } - local->format_size = size; - return 0; + if (size > 0) { + local->format = GF_CALLOC(1, size, gf_crypt_mt_mtd); + if (!local->format) + return ENOMEM; + } + local->format_size = size; + return 0; } -int32_t alloc_format_create(crypt_local_t *local) +int32_t +alloc_format_create(crypt_local_t *local) { - return alloc_format(local, new_format_size()); + return alloc_format(local, new_format_size()); } -void free_format(crypt_local_t *local) +void +free_format(crypt_local_t *local) { - GF_FREE(local->format); + GF_FREE(local->format); } /* * Check compatibility with extracted metadata */ -static int32_t check_file_metadata(struct crypt_inode_info *info) +static int32_t +check_file_metadata(struct crypt_inode_info *info) { - struct object_cipher_info *object = &info->cinfo; - - if (info->nr_minor != CRYPT_XLATOR_ID) { - gf_log("crypt", GF_LOG_WARNING, - "unsupported minor subversion %d", info->nr_minor); - return EINVAL; - } - if (object->o_alg > LAST_CIPHER_ALG) { - gf_log("crypt", GF_LOG_WARNING, - "unsupported cipher algorithm %d", - object->o_alg); - return EINVAL; - } - if (object->o_mode > LAST_CIPHER_MODE) { - gf_log("crypt", GF_LOG_WARNING, - "unsupported cipher mode %d", - object->o_mode); - return EINVAL; - } - if (object->o_block_bits < CRYPT_MIN_BLOCK_BITS || - object->o_block_bits > CRYPT_MAX_BLOCK_BITS) { - gf_log("crypt", GF_LOG_WARNING, "unsupported block bits %d", - object->o_block_bits); - return EINVAL; - } - /* TBD: check data key size */ - return 0; + struct object_cipher_info *object = &info->cinfo; + + if (info->nr_minor != CRYPT_XLATOR_ID) { + gf_log("crypt", GF_LOG_WARNING, "unsupported minor subversion %d", + info->nr_minor); + return EINVAL; + } + if (object->o_alg > LAST_CIPHER_ALG) { + gf_log("crypt", GF_LOG_WARNING, "unsupported cipher algorithm %d", + object->o_alg); + return EINVAL; + } + if (object->o_mode > LAST_CIPHER_MODE) { + gf_log("crypt", GF_LOG_WARNING, "unsupported cipher mode %d", + object->o_mode); + return EINVAL; + } + if (object->o_block_bits < CRYPT_MIN_BLOCK_BITS || + object->o_block_bits > CRYPT_MAX_BLOCK_BITS) { + gf_log("crypt", GF_LOG_WARNING, "unsupported block bits %d", + object->o_block_bits); + return EINVAL; + } + /* TBD: check data key size */ + return 0; } -static size_t format_size_v1(mtd_op_t op, size_t old_size) +static size_t +format_size_v1(mtd_op_t op, size_t old_size) { - - switch (op) { - case MTD_CREATE: - return sizeof(struct mtd_format_v1); - case MTD_OVERWRITE: - return old_size; - case MTD_APPEND: - return old_size + NMTD_8_MAC_SIZE; - case MTD_CUT: - if (old_size > sizeof(struct mtd_format_v1)) - return old_size - NMTD_8_MAC_SIZE; - else - return 0; - default: - gf_log("crypt", GF_LOG_WARNING, "Bad mtd operation"); - return 0; - } + switch (op) { + case MTD_CREATE: + return sizeof(struct mtd_format_v1); + case MTD_OVERWRITE: + return old_size; + case MTD_APPEND: + return old_size + NMTD_8_MAC_SIZE; + case MTD_CUT: + if (old_size > sizeof(struct mtd_format_v1)) + return old_size - NMTD_8_MAC_SIZE; + else + return 0; + default: + gf_log("crypt", GF_LOG_WARNING, "Bad mtd operation"); + return 0; + } } /* * Calculate size of the updated format string. * Returned zero means that we don't need to update the format string. */ -size_t format_size(mtd_op_t op, size_t old_size) +size_t +format_size(mtd_op_t op, size_t old_size) { - size_t versioned; + size_t versioned; - versioned = mtd_loaders[current_mtd_loader()].format_size(op, - old_size - sizeof(struct crypt_format)); - if (versioned != 0) - return versioned + sizeof(struct crypt_format); - return 0; + versioned = mtd_loaders[current_mtd_loader()].format_size( + op, old_size - sizeof(struct crypt_format)); + if (versioned != 0) + return versioned + sizeof(struct crypt_format); + return 0; } /* * size of the format string of newly created file (nr_links = 1) */ -size_t new_format_size(void) +size_t +new_format_size(void) { - return format_size(MTD_CREATE, 0); + return format_size(MTD_CREATE, 0); } /* * Calculate per-link MAC by pathname */ -static int32_t calc_link_mac_v1(struct mtd_format_v1 *fmt, - loc_t *loc, - unsigned char *result, - struct crypt_inode_info *info, - struct master_cipher_info *master) +static int32_t +calc_link_mac_v1(struct mtd_format_v1 *fmt, loc_t *loc, unsigned char *result, + struct crypt_inode_info *info, + struct master_cipher_info *master) { - int32_t ret; - unsigned char nmtd_link_key[16]; - CMAC_CTX *cctx; - size_t len; - - ret = get_nmtd_link_key(loc, master, nmtd_link_key); - if (ret) { - gf_log("crypt", GF_LOG_ERROR, "Can not get nmtd link key"); - return -1; - } - cctx = CMAC_CTX_new(); - if (!cctx) { - gf_log("crypt", GF_LOG_ERROR, "CMAC_CTX_new failed"); - return -1; - } - ret = CMAC_Init(cctx, nmtd_link_key, sizeof(nmtd_link_key), - EVP_aes_128_cbc(), 0); - if (!ret) { - gf_log("crypt", GF_LOG_ERROR, "CMAC_Init failed"); - CMAC_CTX_free(cctx); - return -1; - } - ret = CMAC_Update(cctx, get_NMTD_V1(info), SIZE_OF_NMTD_V1); - if (!ret) { - gf_log("crypt", GF_LOG_ERROR, "CMAC_Update failed"); - CMAC_CTX_free(cctx); - return -1; - } - ret = CMAC_Final(cctx, result, &len); - CMAC_CTX_free(cctx); - if (!ret) { - gf_log("crypt", GF_LOG_ERROR, "CMAC_Final failed"); - return -1; - } - return 0; + int32_t ret; + unsigned char nmtd_link_key[16]; + CMAC_CTX *cctx; + size_t len; + + ret = get_nmtd_link_key(loc, master, nmtd_link_key); + if (ret) { + gf_log("crypt", GF_LOG_ERROR, "Can not get nmtd link key"); + return -1; + } + cctx = CMAC_CTX_new(); + if (!cctx) { + gf_log("crypt", GF_LOG_ERROR, "CMAC_CTX_new failed"); + return -1; + } + ret = CMAC_Init(cctx, nmtd_link_key, sizeof(nmtd_link_key), + EVP_aes_128_cbc(), 0); + if (!ret) { + gf_log("crypt", GF_LOG_ERROR, "CMAC_Init failed"); + CMAC_CTX_free(cctx); + return -1; + } + ret = CMAC_Update(cctx, get_NMTD_V1(info), SIZE_OF_NMTD_V1); + if (!ret) { + gf_log("crypt", GF_LOG_ERROR, "CMAC_Update failed"); + CMAC_CTX_free(cctx); + return -1; + } + ret = CMAC_Final(cctx, result, &len); + CMAC_CTX_free(cctx); + if (!ret) { + gf_log("crypt", GF_LOG_ERROR, "CMAC_Final failed"); + return -1; + } + return 0; } /* * Create per-link MAC of index @idx by pathname */ -static int32_t create_link_mac_v1(struct mtd_format_v1 *fmt, - uint32_t idx, - loc_t *loc, - struct crypt_inode_info *info, - struct master_cipher_info *master) +static int32_t +create_link_mac_v1(struct mtd_format_v1 *fmt, uint32_t idx, loc_t *loc, + struct crypt_inode_info *info, + struct master_cipher_info *master) { - int32_t ret; - unsigned char *mac; - unsigned char cmac[16]; + int32_t ret; + unsigned char *mac; + unsigned char cmac[16]; - mac = get_NMTD_V1_MAC(fmt) + idx * SIZE_OF_NMTD_V1_MAC; + mac = get_NMTD_V1_MAC(fmt) + idx * SIZE_OF_NMTD_V1_MAC; - ret = calc_link_mac_v1(fmt, loc, cmac, info, master); - if (ret) - return -1; - memcpy(mac, cmac, SIZE_OF_NMTD_V1_MAC); - return 0; + ret = calc_link_mac_v1(fmt, loc, cmac, info, master); + if (ret) + return -1; + memcpy(mac, cmac, SIZE_OF_NMTD_V1_MAC); + return 0; } -static int32_t create_format_v1(unsigned char *wire, - loc_t *loc, - struct crypt_inode_info *info, - struct master_cipher_info *master) +static int32_t +create_format_v1(unsigned char *wire, loc_t *loc, struct crypt_inode_info *info, + struct master_cipher_info *master) { - int32_t ret; - struct mtd_format_v1 *fmt; - unsigned char mtd_key[16]; - AES_KEY EMTD_KEY; - unsigned char nmtd_link_key[16]; - uint32_t ad; - GCM128_CONTEXT *gctx; - - fmt = (struct mtd_format_v1 *)wire; - - fmt->minor_id = info->nr_minor; - fmt->alg_id = AES_CIPHER_ALG; - fmt->dkey_factor = master->m_dkey_size >> KEY_FACTOR_BITS; - fmt->block_bits = master->m_block_bits; - fmt->mode_id = master->m_mode; - /* - * retrieve keys for the parts of metadata - */ - ret = get_emtd_file_key(info, master, mtd_key); - if (ret) - return ret; - ret = get_nmtd_link_key(loc, master, nmtd_link_key); - if (ret) - return ret; - - AES_set_encrypt_key(mtd_key, sizeof(mtd_key)*8, &EMTD_KEY); - - gctx = CRYPTO_gcm128_new(&EMTD_KEY, (block128_f)AES_encrypt); - - /* TBD: Check return values */ - - CRYPTO_gcm128_setiv(gctx, info->oid, sizeof(uuid_t)); - - ad = htole32(MTD_LOADER_V1); - ret = CRYPTO_gcm128_aad(gctx, (const unsigned char *)&ad, sizeof(ad)); - if (ret) { - gf_log("crypt", GF_LOG_ERROR, " CRYPTO_gcm128_aad failed"); - CRYPTO_gcm128_release(gctx); - return ret; - } - ret = CRYPTO_gcm128_encrypt(gctx, - get_EMTD_V1(fmt), - get_EMTD_V1(fmt), - SIZE_OF_EMTD_V1); - if (ret) { - gf_log("crypt", GF_LOG_ERROR, " CRYPTO_gcm128_encrypt failed"); - CRYPTO_gcm128_release(gctx); - return ret; - } - /* - * set MAC of encrypted part of metadata - */ - CRYPTO_gcm128_tag(gctx, get_EMTD_V1_MAC(fmt), SIZE_OF_EMTD_V1_MAC); - CRYPTO_gcm128_release(gctx); - /* - * set the first MAC of non-encrypted part of metadata - */ - return create_link_mac_v1(fmt, 0, loc, info, master); + int32_t ret; + struct mtd_format_v1 *fmt; + unsigned char mtd_key[16]; + AES_KEY EMTD_KEY; + unsigned char nmtd_link_key[16]; + uint32_t ad; + GCM128_CONTEXT *gctx; + + fmt = (struct mtd_format_v1 *)wire; + + fmt->minor_id = info->nr_minor; + fmt->alg_id = AES_CIPHER_ALG; + fmt->dkey_factor = master->m_dkey_size >> KEY_FACTOR_BITS; + fmt->block_bits = master->m_block_bits; + fmt->mode_id = master->m_mode; + /* + * retrieve keys for the parts of metadata + */ + ret = get_emtd_file_key(info, master, mtd_key); + if (ret) + return ret; + ret = get_nmtd_link_key(loc, master, nmtd_link_key); + if (ret) + return ret; + + AES_set_encrypt_key(mtd_key, sizeof(mtd_key) * 8, &EMTD_KEY); + + gctx = CRYPTO_gcm128_new(&EMTD_KEY, (block128_f)AES_encrypt); + + /* TBD: Check return values */ + + CRYPTO_gcm128_setiv(gctx, info->oid, sizeof(uuid_t)); + + ad = htole32(MTD_LOADER_V1); + ret = CRYPTO_gcm128_aad(gctx, (const unsigned char *)&ad, sizeof(ad)); + if (ret) { + gf_log("crypt", GF_LOG_ERROR, " CRYPTO_gcm128_aad failed"); + CRYPTO_gcm128_release(gctx); + return ret; + } + ret = CRYPTO_gcm128_encrypt(gctx, get_EMTD_V1(fmt), get_EMTD_V1(fmt), + SIZE_OF_EMTD_V1); + if (ret) { + gf_log("crypt", GF_LOG_ERROR, " CRYPTO_gcm128_encrypt failed"); + CRYPTO_gcm128_release(gctx); + return ret; + } + /* + * set MAC of encrypted part of metadata + */ + CRYPTO_gcm128_tag(gctx, get_EMTD_V1_MAC(fmt), SIZE_OF_EMTD_V1_MAC); + CRYPTO_gcm128_release(gctx); + /* + * set the first MAC of non-encrypted part of metadata + */ + return create_link_mac_v1(fmt, 0, loc, info, master); } /* @@ -253,83 +252,70 @@ static int32_t create_format_v1(unsigned char *wire, * Pack common and version-specific parts of file's metadata * Pre-conditions: @info contains valid object-id. */ -int32_t create_format(unsigned char *wire, - loc_t *loc, - struct crypt_inode_info *info, - struct master_cipher_info *master) +int32_t +create_format(unsigned char *wire, loc_t *loc, struct crypt_inode_info *info, + struct master_cipher_info *master) { - struct crypt_format *fmt = (struct crypt_format *)wire; + struct crypt_format *fmt = (struct crypt_format *)wire; - fmt->loader_id = current_mtd_loader(); + fmt->loader_id = current_mtd_loader(); - wire += sizeof(struct crypt_format); - return mtd_loaders[current_mtd_loader()].create_format(wire, loc, - info, master); + wire += sizeof(struct crypt_format); + return mtd_loaders[current_mtd_loader()].create_format(wire, loc, info, + master); } /* * Append or overwrite per-link mac of @mac_idx index * in accordance with the new pathname */ -int32_t appov_link_mac_v1(unsigned char *new, - unsigned char *old, - uint32_t old_size, - int32_t mac_idx, - loc_t *loc, - struct crypt_inode_info *info, - struct master_cipher_info *master, - crypt_local_t *local) +int32_t +appov_link_mac_v1(unsigned char *new, unsigned char *old, uint32_t old_size, + int32_t mac_idx, loc_t *loc, struct crypt_inode_info *info, + struct master_cipher_info *master, crypt_local_t *local) { - memcpy(new, old, old_size); - return create_link_mac_v1((struct mtd_format_v1 *)new, mac_idx, - loc, info, master); + memcpy(new, old, old_size); + return create_link_mac_v1((struct mtd_format_v1 *)new, mac_idx, loc, info, + master); } /* * Cut per-link mac of @mac_idx index */ -static int32_t cut_link_mac_v1(unsigned char *new, - unsigned char *old, - uint32_t old_size, - int32_t mac_idx, - loc_t *loc, - struct crypt_inode_info *info, - struct master_cipher_info *master, - crypt_local_t *local) +static int32_t +cut_link_mac_v1(unsigned char *new, unsigned char *old, uint32_t old_size, + int32_t mac_idx, loc_t *loc, struct crypt_inode_info *info, + struct master_cipher_info *master, crypt_local_t *local) { - memcpy(new, - old, - sizeof(struct mtd_format_v1) + NMTD_8_MAC_SIZE * (mac_idx - 1)); - - memcpy(new + sizeof(struct mtd_format_v1) + NMTD_8_MAC_SIZE * (mac_idx - 1), - old + sizeof(struct mtd_format_v1) + NMTD_8_MAC_SIZE * mac_idx, - old_size - (sizeof(struct mtd_format_v1) + NMTD_8_MAC_SIZE * mac_idx)); - return 0; + memcpy(new, old, + sizeof(struct mtd_format_v1) + NMTD_8_MAC_SIZE * (mac_idx - 1)); + + memcpy( + new + sizeof(struct mtd_format_v1) + NMTD_8_MAC_SIZE *(mac_idx - 1), + old + sizeof(struct mtd_format_v1) + NMTD_8_MAC_SIZE * mac_idx, + old_size - (sizeof(struct mtd_format_v1) + NMTD_8_MAC_SIZE * mac_idx)); + return 0; } -int32_t update_format_v1(unsigned char *new, - unsigned char *old, - size_t old_len, - int32_t mac_idx, /* of old name */ - mtd_op_t op, - loc_t *loc, - struct crypt_inode_info *info, - struct master_cipher_info *master, - crypt_local_t *local) +int32_t +update_format_v1(unsigned char *new, unsigned char *old, size_t old_len, + int32_t mac_idx, /* of old name */ + mtd_op_t op, loc_t *loc, struct crypt_inode_info *info, + struct master_cipher_info *master, crypt_local_t *local) { - switch (op) { - case MTD_APPEND: - mac_idx = 1 + (old_len - sizeof(struct mtd_format_v1))/8; - case MTD_OVERWRITE: - return appov_link_mac_v1(new, old, old_len, mac_idx, - loc, info, master, local); - case MTD_CUT: - return cut_link_mac_v1(new, old, old_len, mac_idx, - loc, info, master, local); - default: - gf_log("crypt", GF_LOG_ERROR, "Bad mtd operation %d", op); - return -1; - } + switch (op) { + case MTD_APPEND: + mac_idx = 1 + (old_len - sizeof(struct mtd_format_v1)) / 8; + case MTD_OVERWRITE: + return appov_link_mac_v1(new, old, old_len, mac_idx, loc, info, + master, local); + case MTD_CUT: + return cut_link_mac_v1(new, old, old_len, mac_idx, loc, info, + master, local); + default: + gf_log("crypt", GF_LOG_ERROR, "Bad mtd operation %d", op); + return -1; + } } /* @@ -340,29 +326,22 @@ int32_t update_format_v1(unsigned char *new, * ->rename() * */ -int32_t update_format(unsigned char *new, - unsigned char *old, - size_t old_len, - int32_t mac_idx, - mtd_op_t op, - loc_t *loc, - struct crypt_inode_info *info, - struct master_cipher_info *master, - crypt_local_t *local) +int32_t +update_format(unsigned char *new, unsigned char *old, size_t old_len, + int32_t mac_idx, mtd_op_t op, loc_t *loc, + struct crypt_inode_info *info, struct master_cipher_info *master, + crypt_local_t *local) { - if (!new) - return 0; - memcpy(new, old, sizeof(struct crypt_format)); - - old += sizeof(struct crypt_format); - new += sizeof(struct crypt_format); - old_len -= sizeof(struct crypt_format); - - return mtd_loaders[current_mtd_loader()].update_format(new, old, - old_len, - mac_idx, op, - loc, info, - master, local); + if (!new) + return 0; + memcpy(new, old, sizeof(struct crypt_format)); + + old += sizeof(struct crypt_format); + new += sizeof(struct crypt_format); + old_len -= sizeof(struct crypt_format); + + return mtd_loaders[current_mtd_loader()].update_format( + new, old, old_len, mac_idx, op, loc, info, master, local); } /* @@ -370,27 +349,26 @@ int32_t update_format(unsigned char *new, * Return < 0 on errors; * Return number of object-id MACs (>= 1) on success */ -int32_t check_format_v1(uint32_t len, unsigned char *wire) +int32_t +check_format_v1(uint32_t len, unsigned char *wire) { - uint32_t nr_links; - - if (len < sizeof(struct mtd_format_v1)) { - gf_log("crypt", GF_LOG_ERROR, - "v1-loader: bad metadata size %d", len); - goto error; - } - len -= sizeof(struct mtd_format_v1); - if (len % sizeof(nmtd_8_mac_t)) { - gf_log("crypt", GF_LOG_ERROR, - "v1-loader: bad metadata format"); - goto error; - } - nr_links = 1 + len / sizeof(nmtd_8_mac_t); - if (nr_links > _POSIX_LINK_MAX) - goto error; - return nr_links; - error: - return EIO; + uint32_t nr_links; + + if (len < sizeof(struct mtd_format_v1)) { + gf_log("crypt", GF_LOG_ERROR, "v1-loader: bad metadata size %d", len); + goto error; + } + len -= sizeof(struct mtd_format_v1); + if (len % sizeof(nmtd_8_mac_t)) { + gf_log("crypt", GF_LOG_ERROR, "v1-loader: bad metadata format"); + goto error; + } + nr_links = 1 + len / sizeof(nmtd_8_mac_t); + if (nr_links > _POSIX_LINK_MAX) + goto error; + return nr_links; +error: + return EIO; } /* @@ -401,24 +379,24 @@ int32_t check_format_v1(uint32_t len, unsigned char *wire) * 0 on failed verification; * 1 on successful verification */ -static int32_t verify_link_mac_v1(struct mtd_format_v1 *fmt, - uint32_t idx /* index of the mac to verify */, - loc_t *loc, - struct crypt_inode_info *info, - struct master_cipher_info *master) +static int32_t +verify_link_mac_v1(struct mtd_format_v1 *fmt, + uint32_t idx /* index of the mac to verify */, loc_t *loc, + struct crypt_inode_info *info, + struct master_cipher_info *master) { - int32_t ret; - unsigned char *mac; - unsigned char cmac[16]; - - mac = get_NMTD_V1_MAC(fmt) + idx * SIZE_OF_NMTD_V1_MAC; - - ret = calc_link_mac_v1(fmt, loc, cmac, info, master); - if (ret) - return -1; - if (memcmp(cmac, mac, SIZE_OF_NMTD_V1_MAC)) - return 0; - return 1; + int32_t ret; + unsigned char *mac; + unsigned char cmac[16]; + + mac = get_NMTD_V1_MAC(fmt) + idx * SIZE_OF_NMTD_V1_MAC; + + ret = calc_link_mac_v1(fmt, loc, cmac, info, master); + if (ret) + return -1; + if (memcmp(cmac, mac, SIZE_OF_NMTD_V1_MAC)) + return 0; + return 1; } /* @@ -427,133 +405,127 @@ static int32_t verify_link_mac_v1(struct mtd_format_v1 *fmt, * return index of the MAC, if it was found; * return < 0 on errors, or if the MAC wasn't found */ -static int32_t lookup_link_mac_v1(struct mtd_format_v1 *fmt, - uint32_t nr_macs, - loc_t *loc, - struct crypt_inode_info *info, - struct master_cipher_info *master) +static int32_t +lookup_link_mac_v1(struct mtd_format_v1 *fmt, uint32_t nr_macs, loc_t *loc, + struct crypt_inode_info *info, + struct master_cipher_info *master) { - int32_t ret; - uint32_t idx; - - for (idx = 0; idx < nr_macs; idx++) { - ret = verify_link_mac_v1(fmt, idx, loc, info, master); - if (ret < 0) - return ret; - if (ret > 0) - return idx; - } - return -ENOENT; + int32_t ret; + uint32_t idx; + + for (idx = 0; idx < nr_macs; idx++) { + ret = verify_link_mac_v1(fmt, idx, loc, info, master); + if (ret < 0) + return ret; + if (ret > 0) + return idx; + } + return -ENOENT; } /* * Extract version-specific part of metadata */ -static int32_t open_format_v1(unsigned char *wire, - int32_t len, - loc_t *loc, - struct crypt_inode_info *info, - struct master_cipher_info *master, - crypt_local_t *local, - gf_boolean_t load_info) +static int32_t +open_format_v1(unsigned char *wire, int32_t len, loc_t *loc, + struct crypt_inode_info *info, struct master_cipher_info *master, + crypt_local_t *local, gf_boolean_t load_info) { - int32_t ret; - int32_t num_nmtd_macs; - struct mtd_format_v1 *fmt; - unsigned char mtd_key[16]; - AES_KEY EMTD_KEY; - GCM128_CONTEXT *gctx; - uint32_t ad; - emtd_8_mac_t gmac; - struct object_cipher_info *object; - - num_nmtd_macs = check_format_v1(len, wire); - if (num_nmtd_macs <= 0) - return EIO; - - ret = lookup_link_mac_v1((struct mtd_format_v1 *)wire, - num_nmtd_macs, loc, info, master); - if (ret < 0) { - gf_log("crypt", GF_LOG_ERROR, "NMTD verification failed"); - return EINVAL; - } - - local->mac_idx = ret; - if (load_info == _gf_false) - /* the case of partial open */ - return 0; - - fmt = GF_MALLOC(len, gf_crypt_mt_mtd); - if (!fmt) - return ENOMEM; - memcpy(fmt, wire, len); - - object = &info->cinfo; - - ret = get_emtd_file_key(info, master, mtd_key); - if (ret) { - gf_log("crypt", GF_LOG_ERROR, "Can not retrieve metadata key"); - goto out; - } - /* - * decrypt encrypted meta-data - */ - ret = AES_set_encrypt_key(mtd_key, sizeof(mtd_key)*8, &EMTD_KEY); - if (ret < 0) { - gf_log("crypt", GF_LOG_ERROR, "Can not set encrypt key"); - ret = EIO; - goto out; - } - gctx = CRYPTO_gcm128_new(&EMTD_KEY, (block128_f)AES_encrypt); - if (!gctx) { - gf_log("crypt", GF_LOG_ERROR, "Can not alloc gcm context"); - ret = ENOMEM; - goto out; - } - CRYPTO_gcm128_setiv(gctx, info->oid, sizeof(uuid_t)); - - ad = htole32(MTD_LOADER_V1); - ret = CRYPTO_gcm128_aad(gctx, (const unsigned char *)&ad, sizeof(ad)); - if (ret) { - gf_log("crypt", GF_LOG_ERROR, " CRYPTO_gcm128_aad failed"); - CRYPTO_gcm128_release(gctx); - ret = EIO; - goto out; - } - ret = CRYPTO_gcm128_decrypt(gctx, - get_EMTD_V1(fmt), - get_EMTD_V1(fmt), - SIZE_OF_EMTD_V1); - if (ret) { - gf_log("crypt", GF_LOG_ERROR, " CRYPTO_gcm128_decrypt failed"); - CRYPTO_gcm128_release(gctx); - ret = EIO; - goto out; - } - /* - * verify metadata - */ - CRYPTO_gcm128_tag(gctx, gmac, sizeof(gmac)); - CRYPTO_gcm128_release(gctx); - if (memcmp(gmac, get_EMTD_V1_MAC(fmt), SIZE_OF_EMTD_V1_MAC)) { - gf_log("crypt", GF_LOG_ERROR, "EMTD verification failed"); - ret = EINVAL; - goto out; - } - /* - * load verified metadata to the private part of inode - */ - info->nr_minor = fmt->minor_id; - - object->o_alg = fmt->alg_id; - object->o_dkey_size = fmt->dkey_factor << KEY_FACTOR_BITS; - object->o_block_bits = fmt->block_bits; - object->o_mode = fmt->mode_id; - - ret = check_file_metadata(info); - out: - GF_FREE(fmt); - return ret; + int32_t ret; + int32_t num_nmtd_macs; + struct mtd_format_v1 *fmt; + unsigned char mtd_key[16]; + AES_KEY EMTD_KEY; + GCM128_CONTEXT *gctx; + uint32_t ad; + emtd_8_mac_t gmac; + struct object_cipher_info *object; + + num_nmtd_macs = check_format_v1(len, wire); + if (num_nmtd_macs <= 0) + return EIO; + + ret = lookup_link_mac_v1((struct mtd_format_v1 *)wire, num_nmtd_macs, loc, + info, master); + if (ret < 0) { + gf_log("crypt", GF_LOG_ERROR, "NMTD verification failed"); + return EINVAL; + } + + local->mac_idx = ret; + if (load_info == _gf_false) + /* the case of partial open */ + return 0; + + fmt = GF_MALLOC(len, gf_crypt_mt_mtd); + if (!fmt) + return ENOMEM; + memcpy(fmt, wire, len); + + object = &info->cinfo; + + ret = get_emtd_file_key(info, master, mtd_key); + if (ret) { + gf_log("crypt", GF_LOG_ERROR, "Can not retrieve metadata key"); + goto out; + } + /* + * decrypt encrypted meta-data + */ + ret = AES_set_encrypt_key(mtd_key, sizeof(mtd_key) * 8, &EMTD_KEY); + if (ret < 0) { + gf_log("crypt", GF_LOG_ERROR, "Can not set encrypt key"); + ret = EIO; + goto out; + } + gctx = CRYPTO_gcm128_new(&EMTD_KEY, (block128_f)AES_encrypt); + if (!gctx) { + gf_log("crypt", GF_LOG_ERROR, "Can not alloc gcm context"); + ret = ENOMEM; + goto out; + } + CRYPTO_gcm128_setiv(gctx, info->oid, sizeof(uuid_t)); + + ad = htole32(MTD_LOADER_V1); + ret = CRYPTO_gcm128_aad(gctx, (const unsigned char *)&ad, sizeof(ad)); + if (ret) { + gf_log("crypt", GF_LOG_ERROR, " CRYPTO_gcm128_aad failed"); + CRYPTO_gcm128_release(gctx); + ret = EIO; + goto out; + } + ret = CRYPTO_gcm128_decrypt(gctx, get_EMTD_V1(fmt), get_EMTD_V1(fmt), + SIZE_OF_EMTD_V1); + if (ret) { + gf_log("crypt", GF_LOG_ERROR, " CRYPTO_gcm128_decrypt failed"); + CRYPTO_gcm128_release(gctx); + ret = EIO; + goto out; + } + /* + * verify metadata + */ + CRYPTO_gcm128_tag(gctx, gmac, sizeof(gmac)); + CRYPTO_gcm128_release(gctx); + if (memcmp(gmac, get_EMTD_V1_MAC(fmt), SIZE_OF_EMTD_V1_MAC)) { + gf_log("crypt", GF_LOG_ERROR, "EMTD verification failed"); + ret = EINVAL; + goto out; + } + /* + * load verified metadata to the private part of inode + */ + info->nr_minor = fmt->minor_id; + + object->o_alg = fmt->alg_id; + object->o_dkey_size = fmt->dkey_factor << KEY_FACTOR_BITS; + object->o_block_bits = fmt->block_bits; + object->o_mode = fmt->mode_id; + + ret = check_file_metadata(info); +out: + GF_FREE(fmt); + return ret; } /* @@ -561,46 +533,35 @@ static int32_t open_format_v1(unsigned char *wire, * extract crypt-specific attribute and populate @info * with them (optional) */ -int32_t open_format(unsigned char *str, - int32_t len, - loc_t *loc, - struct crypt_inode_info *info, - struct master_cipher_info *master, - crypt_local_t *local, - gf_boolean_t load_info) +int32_t +open_format(unsigned char *str, int32_t len, loc_t *loc, + struct crypt_inode_info *info, struct master_cipher_info *master, + crypt_local_t *local, gf_boolean_t load_info) { - struct crypt_format *fmt; - if (len < sizeof(*fmt)) { - gf_log("crypt", GF_LOG_ERROR, "Bad core format"); - return EIO; - } - fmt = (struct crypt_format *)str; - - if (fmt->loader_id >= LAST_MTD_LOADER) { - gf_log("crypt", GF_LOG_ERROR, - "Unsupported loader id %d", fmt->loader_id); - return EINVAL; - } - str += sizeof(*fmt); - len -= sizeof(*fmt); - - return mtd_loaders[fmt->loader_id].open_format(str, - len, - loc, - info, - master, - local, - load_info); + struct crypt_format *fmt; + if (len < sizeof(*fmt)) { + gf_log("crypt", GF_LOG_ERROR, "Bad core format"); + return EIO; + } + fmt = (struct crypt_format *)str; + + if (fmt->loader_id >= LAST_MTD_LOADER) { + gf_log("crypt", GF_LOG_ERROR, "Unsupported loader id %d", + fmt->loader_id); + return EINVAL; + } + str += sizeof(*fmt); + len -= sizeof(*fmt); + + return mtd_loaders[fmt->loader_id].open_format(str, len, loc, info, master, + local, load_info); } -struct crypt_mtd_loader mtd_loaders [LAST_MTD_LOADER] = { - [MTD_LOADER_V1] = - {.format_size = format_size_v1, - .create_format = create_format_v1, - .open_format = open_format_v1, - .update_format = update_format_v1 - } -}; +struct crypt_mtd_loader mtd_loaders[LAST_MTD_LOADER] = { + [MTD_LOADER_V1] = {.format_size = format_size_v1, + .create_format = create_format_v1, + .open_format = open_format_v1, + .update_format = update_format_v1}}; /* Local variables: |