diff options
Diffstat (limited to 'xlators/encryption/crypt/src/keys.c')
| -rw-r--r-- | xlators/encryption/crypt/src/keys.c | 368 | 
1 files changed, 171 insertions, 197 deletions
diff --git a/xlators/encryption/crypt/src/keys.c b/xlators/encryption/crypt/src/keys.c index e9da55960c8..a9357005a36 100644 --- a/xlators/encryption/crypt/src/keys.c +++ b/xlators/encryption/crypt/src/keys.c @@ -34,18 +34,19 @@   */  #if DEBUG_CRYPT -static void check_prf_iters(uint32_t num_iters) +static void +check_prf_iters(uint32_t num_iters)  { -	if (num_iters == 0) -		gf_log ("crypt", GF_LOG_DEBUG, -			"bad number of prf iterations : %d", num_iters); +    if (num_iters == 0) +        gf_log("crypt", GF_LOG_DEBUG, "bad number of prf iterations : %d", +               num_iters);  }  #else  #define check_prf_iters(num_iters) noop  #endif /* DEBUG_CRYPT */ -unsigned char crypt_fake_oid[16] = -	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +unsigned char crypt_fake_oid[16] = {0, 0, 0, 0, 0, 0, 0, 0, +                                    0, 0, 0, 0, 0, 0, 0, 0};  /*   * derive key in the counter mode using @@ -53,250 +54,223 @@ unsigned char crypt_fake_oid[16] =   * NIST Special Publication 800-108, 5.1)   */ -#define PRF_OUTPUT_SIZE  SHA256_DIGEST_LENGTH +#define PRF_OUTPUT_SIZE SHA256_DIGEST_LENGTH -static int32_t kderive_init(struct kderive_context *ctx, -			    const unsigned char *pkey, /* parent key */ -			    uint32_t pkey_size,  /* parent key size */ -			    const unsigned char *idctx, /* id-context */ -			    uint32_t idctx_size, -			    crypt_key_type type  /* type of child key */) +static int32_t +kderive_init(struct kderive_context *ctx, +             const unsigned char *pkey,  /* parent key */ +             uint32_t pkey_size,         /* parent key size */ +             const unsigned char *idctx, /* id-context */ +             uint32_t idctx_size, crypt_key_type type /* type of child key */)  { -	unsigned char *pos; -	uint32_t llen = strlen(crypt_keys[type].label); -	/* -	 * Compoud the fixed input data for KDF: -	 * [i]_2 || Label || 0x00 || Id-Context || [L]_2), -	 * NIST SP 800-108, 5.1 -	 */ -	ctx->fid_len = -		sizeof(uint32_t) + -		llen + -		1 + -		idctx_size + -		sizeof(uint32_t); - -	ctx->fid = GF_CALLOC(ctx->fid_len, 1, gf_crypt_mt_key); -	if (!ctx->fid) -		return ENOMEM; -	ctx->out_len = round_up(crypt_keys[type].len >> 3, -				PRF_OUTPUT_SIZE); -	ctx->out = GF_CALLOC(ctx->out_len, 1, gf_crypt_mt_key); -	if (!ctx->out) { -		GF_FREE(ctx->fid); -		return ENOMEM; -	} -	ctx->pkey = pkey; -	ctx->pkey_len = pkey_size; -	ctx->ckey_len = crypt_keys[type].len; - -	pos = ctx->fid; - -	/* counter will be set up in kderive_rfn() */ -	pos += sizeof(uint32_t); - -	memcpy(pos, crypt_keys[type].label, llen); -	pos += llen; - -	/* set up zero octet */ -	*pos = 0; -	pos += 1; - -	memcpy(pos, idctx, idctx_size); -	pos += idctx_size; - -	*((uint32_t *)pos) = htobe32(ctx->ckey_len); - -	return 0; +    unsigned char *pos; +    uint32_t llen = strlen(crypt_keys[type].label); +    /* +     * Compoud the fixed input data for KDF: +     * [i]_2 || Label || 0x00 || Id-Context || [L]_2), +     * NIST SP 800-108, 5.1 +     */ +    ctx->fid_len = sizeof(uint32_t) + llen + 1 + idctx_size + sizeof(uint32_t); + +    ctx->fid = GF_CALLOC(ctx->fid_len, 1, gf_crypt_mt_key); +    if (!ctx->fid) +        return ENOMEM; +    ctx->out_len = round_up(crypt_keys[type].len >> 3, PRF_OUTPUT_SIZE); +    ctx->out = GF_CALLOC(ctx->out_len, 1, gf_crypt_mt_key); +    if (!ctx->out) { +        GF_FREE(ctx->fid); +        return ENOMEM; +    } +    ctx->pkey = pkey; +    ctx->pkey_len = pkey_size; +    ctx->ckey_len = crypt_keys[type].len; + +    pos = ctx->fid; + +    /* counter will be set up in kderive_rfn() */ +    pos += sizeof(uint32_t); + +    memcpy(pos, crypt_keys[type].label, llen); +    pos += llen; + +    /* set up zero octet */ +    *pos = 0; +    pos += 1; + +    memcpy(pos, idctx, idctx_size); +    pos += idctx_size; + +    *((uint32_t *)pos) = htobe32(ctx->ckey_len); + +    return 0;  } -static void kderive_update(struct kderive_context *ctx) +static void +kderive_update(struct kderive_context *ctx)  { -	uint32_t i; +    uint32_t i;  #if (OPENSSL_VERSION_NUMBER < 0x1010002f) -	HMAC_CTX hctx; +    HMAC_CTX hctx;  #endif -        HMAC_CTX *phctx = NULL; -	unsigned char *pos = ctx->out; -	uint32_t *p_iter = (uint32_t *)ctx->fid; -	uint32_t num_iters = ctx->out_len / PRF_OUTPUT_SIZE; +    HMAC_CTX *phctx = NULL; +    unsigned char *pos = ctx->out; +    uint32_t *p_iter = (uint32_t *)ctx->fid; +    uint32_t num_iters = ctx->out_len / PRF_OUTPUT_SIZE; -	check_prf_iters(num_iters); +    check_prf_iters(num_iters);  #if (OPENSSL_VERSION_NUMBER < 0x1010002f) -	HMAC_CTX_init(&hctx); -        phctx = &hctx; +    HMAC_CTX_init(&hctx); +    phctx = &hctx;  #else -        phctx = HMAC_CTX_new(); -        /* I guess we presume it was successful? */ +    phctx = HMAC_CTX_new(); +    /* I guess we presume it was successful? */  #endif -	for (i = 0; i < num_iters; i++) { -		/* -		 * update the iteration number in the fid -		 */ -		*p_iter = htobe32(i); -		HMAC_Init_ex(phctx, -			     ctx->pkey, ctx->pkey_len >> 3, -			     EVP_sha256(), -			     NULL); -		HMAC_Update(phctx, ctx->fid, ctx->fid_len); -		HMAC_Final(phctx, pos, NULL); - -		pos += PRF_OUTPUT_SIZE; -	} +    for (i = 0; i < num_iters; i++) { +        /* +         * update the iteration number in the fid +         */ +        *p_iter = htobe32(i); +        HMAC_Init_ex(phctx, ctx->pkey, ctx->pkey_len >> 3, EVP_sha256(), NULL); +        HMAC_Update(phctx, ctx->fid, ctx->fid_len); +        HMAC_Final(phctx, pos, NULL); + +        pos += PRF_OUTPUT_SIZE; +    }  #if (OPENSSL_VERSION_NUMBER < 0x1010002f) -	HMAC_CTX_cleanup(phctx); +    HMAC_CTX_cleanup(phctx);  #else -        HMAC_CTX_free(phctx); +    HMAC_CTX_free(phctx);  #endif  } -static void kderive_final(struct kderive_context *ctx, unsigned char *child) +static void +kderive_final(struct kderive_context *ctx, unsigned char *child)  { -	memcpy(child, ctx->out, ctx->ckey_len >> 3); -	GF_FREE(ctx->fid); -	GF_FREE(ctx->out); -	memset(ctx, 0, sizeof(*ctx)); +    memcpy(child, ctx->out, ctx->ckey_len >> 3); +    GF_FREE(ctx->fid); +    GF_FREE(ctx->out); +    memset(ctx, 0, sizeof(*ctx));  }  /*   * derive per-volume key for object ids aithentication   */ -int32_t get_nmtd_vol_key(struct master_cipher_info *master) +int32_t +get_nmtd_vol_key(struct master_cipher_info *master)  { -	int32_t ret; -	struct kderive_context ctx; - -	ret = kderive_init(&ctx, -			   master->m_key, -			   master_key_size(), -			   crypt_fake_oid, sizeof(uuid_t), NMTD_VOL_KEY); -	if (ret) -		return ret; -	kderive_update(&ctx); -	kderive_final(&ctx, master->m_nmtd_key); -	return 0; +    int32_t ret; +    struct kderive_context ctx; + +    ret = kderive_init(&ctx, master->m_key, master_key_size(), crypt_fake_oid, +                       sizeof(uuid_t), NMTD_VOL_KEY); +    if (ret) +        return ret; +    kderive_update(&ctx); +    kderive_final(&ctx, master->m_nmtd_key); +    return 0;  }  /*   * derive per-link key for aithentication of non-encrypted   * meta-data (nmtd)   */ -int32_t get_nmtd_link_key(loc_t *loc, -			  struct master_cipher_info *master, -			  unsigned char *result) +int32_t +get_nmtd_link_key(loc_t *loc, struct master_cipher_info *master, +                  unsigned char *result)  { -	int32_t ret; -	struct kderive_context ctx; - -	ret = kderive_init(&ctx, -			   master->m_nmtd_key, -			   nmtd_vol_key_size(), -			   (const unsigned char *)loc->path, -			   strlen(loc->path), NMTD_LINK_KEY); -	if (ret) -		return ret; -	kderive_update(&ctx); -	kderive_final(&ctx, result); -	return 0; +    int32_t ret; +    struct kderive_context ctx; + +    ret = kderive_init(&ctx, master->m_nmtd_key, nmtd_vol_key_size(), +                       (const unsigned char *)loc->path, strlen(loc->path), +                       NMTD_LINK_KEY); +    if (ret) +        return ret; +    kderive_update(&ctx); +    kderive_final(&ctx, result); +    return 0;  }  /*   * derive per-file key for encryption and authentication   * of encrypted part of metadata (emtd)   */ -int32_t get_emtd_file_key(struct crypt_inode_info *info, -			  struct master_cipher_info *master, -			  unsigned char *result) +int32_t +get_emtd_file_key(struct crypt_inode_info *info, +                  struct master_cipher_info *master, unsigned char *result)  { -	int32_t ret; -	struct kderive_context ctx; - -	ret = kderive_init(&ctx, -			   master->m_key, -			   master_key_size(), -			   info->oid, sizeof(uuid_t), EMTD_FILE_KEY); -	if (ret) -		return ret; -	kderive_update(&ctx); -	kderive_final(&ctx, result); -	return 0; +    int32_t ret; +    struct kderive_context ctx; + +    ret = kderive_init(&ctx, master->m_key, master_key_size(), info->oid, +                       sizeof(uuid_t), EMTD_FILE_KEY); +    if (ret) +        return ret; +    kderive_update(&ctx); +    kderive_final(&ctx, result); +    return 0;  } -static int32_t data_key_type_by_size(uint32_t keysize, crypt_key_type *type) +static int32_t +data_key_type_by_size(uint32_t keysize, crypt_key_type *type)  { -	int32_t ret = 0; -	switch (keysize) { -	case 256: -		*type = DATA_FILE_KEY_256; -		break; -	case 512: -		*type = DATA_FILE_KEY_512; -		break; -	default: -		gf_log("crypt", GF_LOG_ERROR, "Unsupported data key size %d", -		       keysize); -		ret = ENOTSUP; -		break; -	} -	return ret; +    int32_t ret = 0; +    switch (keysize) { +        case 256: +            *type = DATA_FILE_KEY_256; +            break; +        case 512: +            *type = DATA_FILE_KEY_512; +            break; +        default: +            gf_log("crypt", GF_LOG_ERROR, "Unsupported data key size %d", +                   keysize); +            ret = ENOTSUP; +            break; +    } +    return ret;  }  /*   * derive per-file key for data encryption   */ -int32_t get_data_file_key(struct crypt_inode_info *info, -			  struct master_cipher_info *master, -			  uint32_t keysize, -			  unsigned char *key) +int32_t +get_data_file_key(struct crypt_inode_info *info, +                  struct master_cipher_info *master, uint32_t keysize, +                  unsigned char *key)  { -	int32_t ret; -	struct kderive_context ctx; -	crypt_key_type type; - -	ret = data_key_type_by_size(keysize, &type); -	if (ret) -		return ret; -	ret = kderive_init(&ctx, -			   master->m_key, -			   master_key_size(), -			   info->oid, sizeof(uuid_t), type); -	if (ret) -		return ret; -	kderive_update(&ctx); -	kderive_final(&ctx, key); -	return 0; +    int32_t ret; +    struct kderive_context ctx; +    crypt_key_type type; + +    ret = data_key_type_by_size(keysize, &type); +    if (ret) +        return ret; +    ret = kderive_init(&ctx, master->m_key, master_key_size(), info->oid, +                       sizeof(uuid_t), type); +    if (ret) +        return ret; +    kderive_update(&ctx); +    kderive_final(&ctx, key); +    return 0;  }  /*   * NOTE: Don't change existing keys: it will break compatibility;   */  struct crypt_key crypt_keys[LAST_KEY_TYPE] = { -	[MASTER_VOL_KEY] = -	{ .len = MASTER_VOL_KEY_SIZE << 3, -	  .label = "volume-master", -	}, -	[NMTD_VOL_KEY] = -	{ .len = NMTD_VOL_KEY_SIZE << 3, -	  .label = "volume-nmtd-key-generation" -	}, -	[NMTD_LINK_KEY] = -	{ .len = 128, -	  .label = "link-nmtd-authentication" -	}, -	[EMTD_FILE_KEY] = -	{ .len = 128, -	  .label = "file-emtd-encryption-and-auth" -	}, -	[DATA_FILE_KEY_256] = -	{ .len = 256, -	  .label = "file-data-encryption-256" -	}, -	[DATA_FILE_KEY_512] = -	{ .len = 512, -	  .label = "file-data-encryption-512" -	} -}; +    [MASTER_VOL_KEY] = +        { +            .len = MASTER_VOL_KEY_SIZE << 3, +            .label = "volume-master", +        }, +    [NMTD_VOL_KEY] = {.len = NMTD_VOL_KEY_SIZE << 3, +                      .label = "volume-nmtd-key-generation"}, +    [NMTD_LINK_KEY] = {.len = 128, .label = "link-nmtd-authentication"}, +    [EMTD_FILE_KEY] = {.len = 128, .label = "file-emtd-encryption-and-auth"}, +    [DATA_FILE_KEY_256] = {.len = 256, .label = "file-data-encryption-256"}, +    [DATA_FILE_KEY_512] = {.len = 512, .label = "file-data-encryption-512"}};  /*    Local variables:  | 
