⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keystore.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		ecryptfs_dump_hex(key_rec->enc_key, key_rec->enc_key_size);	}encrypted_session_key_set:	/* This format is inspired by OpenPGP; see RFC 2440	 * packet tag 1 */	max_packet_size = (1                         /* Tag 1 identifier */			   + 3                       /* Max Tag 1 packet size */			   + 1                       /* Version */			   + ECRYPTFS_SIG_SIZE       /* Key identifier */			   + 1                       /* Cipher identifier */			   + key_rec->enc_key_size); /* Encrypted key size */	if (max_packet_size > (*remaining_bytes)) {		printk(KERN_ERR "Packet length larger than maximum allowable; "		       "need up to [%td] bytes, but there are only [%td] "		       "available\n", max_packet_size, (*remaining_bytes));		rc = -EINVAL;		goto out;	}	dest[(*packet_size)++] = ECRYPTFS_TAG_1_PACKET_TYPE;	rc = write_packet_length(&dest[(*packet_size)], (max_packet_size - 4),				 &packet_size_length);	if (rc) {		ecryptfs_printk(KERN_ERR, "Error generating tag 1 packet "				"header; cannot generate packet length\n");		goto out;	}	(*packet_size) += packet_size_length;	dest[(*packet_size)++] = 0x03; /* version 3 */	memcpy(&dest[(*packet_size)], key_rec->sig, ECRYPTFS_SIG_SIZE);	(*packet_size) += ECRYPTFS_SIG_SIZE;	dest[(*packet_size)++] = RFC2440_CIPHER_RSA;	memcpy(&dest[(*packet_size)], key_rec->enc_key,	       key_rec->enc_key_size);	(*packet_size) += key_rec->enc_key_size;out:	if (rc)		(*packet_size) = 0;	else		(*remaining_bytes) -= (*packet_size);	return rc;}/** * write_tag_11_packet * @dest: Target into which Tag 11 packet is to be written * @remaining_bytes: Maximum packet length * @contents: Byte array of contents to copy in * @contents_length: Number of bytes in contents * @packet_length: Length of the Tag 11 packet written; zero on error * * Returns zero on success; non-zero on error. */static intwrite_tag_11_packet(char *dest, size_t *remaining_bytes, char *contents,		    size_t contents_length, size_t *packet_length){	size_t packet_size_length;	size_t max_packet_size;	int rc = 0;	(*packet_length) = 0;	/* This format is inspired by OpenPGP; see RFC 2440	 * packet tag 11 */	max_packet_size = (1                   /* Tag 11 identifier */			   + 3                 /* Max Tag 11 packet size */			   + 1                 /* Binary format specifier */			   + 1                 /* Filename length */			   + 8                 /* Filename ("_CONSOLE") */			   + 4                 /* Modification date */			   + contents_length); /* Literal data */	if (max_packet_size > (*remaining_bytes)) {		printk(KERN_ERR "Packet length larger than maximum allowable; "		       "need up to [%td] bytes, but there are only [%td] "		       "available\n", max_packet_size, (*remaining_bytes));		rc = -EINVAL;		goto out;	}	dest[(*packet_length)++] = ECRYPTFS_TAG_11_PACKET_TYPE;	rc = write_packet_length(&dest[(*packet_length)],				 (max_packet_size - 4), &packet_size_length);	if (rc) {		printk(KERN_ERR "Error generating tag 11 packet header; cannot "		       "generate packet length. rc = [%d]\n", rc);		goto out;	}	(*packet_length) += packet_size_length;	dest[(*packet_length)++] = 0x62; /* binary data format specifier */	dest[(*packet_length)++] = 8;	memcpy(&dest[(*packet_length)], "_CONSOLE", 8);	(*packet_length) += 8;	memset(&dest[(*packet_length)], 0x00, 4);	(*packet_length) += 4;	memcpy(&dest[(*packet_length)], contents, contents_length);	(*packet_length) += contents_length; out:	if (rc)		(*packet_length) = 0;	else		(*remaining_bytes) -= (*packet_length);	return rc;}/** * write_tag_3_packet * @dest: Buffer into which to write the packet * @remaining_bytes: Maximum number of bytes that can be written * @auth_tok: Authentication token * @crypt_stat: The cryptographic context * @key_rec: encrypted key * @packet_size: This function will write the number of bytes that end *               up constituting the packet; set to zero on error * * Returns zero on success; non-zero on error. */static intwrite_tag_3_packet(char *dest, size_t *remaining_bytes,		   struct ecryptfs_auth_tok *auth_tok,		   struct ecryptfs_crypt_stat *crypt_stat,		   struct ecryptfs_key_record *key_rec, size_t *packet_size){	size_t i;	size_t encrypted_session_key_valid = 0;	char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES];	struct scatterlist dst_sg;	struct scatterlist src_sg;	struct mutex *tfm_mutex = NULL;	size_t cipher_code;	size_t packet_size_length;	size_t max_packet_size;	struct ecryptfs_mount_crypt_stat *mount_crypt_stat =		crypt_stat->mount_crypt_stat;	struct blkcipher_desc desc = {		.tfm = NULL,		.flags = CRYPTO_TFM_REQ_MAY_SLEEP	};	int rc = 0;	(*packet_size) = 0;	ecryptfs_from_hex(key_rec->sig, auth_tok->token.password.signature,			  ECRYPTFS_SIG_SIZE);	rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&desc.tfm, &tfm_mutex,							crypt_stat->cipher);	if (unlikely(rc)) {		printk(KERN_ERR "Internal error whilst attempting to get "		       "tfm and mutex for cipher name [%s]; rc = [%d]\n",		       crypt_stat->cipher, rc);		goto out;	}	if (mount_crypt_stat->global_default_cipher_key_size == 0) {		struct blkcipher_alg *alg = crypto_blkcipher_alg(desc.tfm);		printk(KERN_WARNING "No key size specified at mount; "		       "defaulting to [%d]\n", alg->max_keysize);		mount_crypt_stat->global_default_cipher_key_size =			alg->max_keysize;	}	if (crypt_stat->key_size == 0)		crypt_stat->key_size =			mount_crypt_stat->global_default_cipher_key_size;	if (auth_tok->session_key.encrypted_key_size == 0)		auth_tok->session_key.encrypted_key_size =			crypt_stat->key_size;	if (crypt_stat->key_size == 24	    && strcmp("aes", crypt_stat->cipher) == 0) {		memset((crypt_stat->key + 24), 0, 8);		auth_tok->session_key.encrypted_key_size = 32;	} else		auth_tok->session_key.encrypted_key_size = crypt_stat->key_size;	key_rec->enc_key_size =		auth_tok->session_key.encrypted_key_size;	encrypted_session_key_valid = 0;	for (i = 0; i < auth_tok->session_key.encrypted_key_size; i++)		encrypted_session_key_valid |=			auth_tok->session_key.encrypted_key[i];	if (encrypted_session_key_valid) {		ecryptfs_printk(KERN_DEBUG, "encrypted_session_key_valid != 0; "				"using auth_tok->session_key.encrypted_key, "				"where key_rec->enc_key_size = [%d]\n",				key_rec->enc_key_size);		memcpy(key_rec->enc_key,		       auth_tok->session_key.encrypted_key,		       key_rec->enc_key_size);		goto encrypted_session_key_set;	}	if (auth_tok->token.password.flags &	    ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET) {		ecryptfs_printk(KERN_DEBUG, "Using previously generated "				"session key encryption key of size [%d]\n",				auth_tok->token.password.				session_key_encryption_key_bytes);		memcpy(session_key_encryption_key,		       auth_tok->token.password.session_key_encryption_key,		       crypt_stat->key_size);		ecryptfs_printk(KERN_DEBUG,				"Cached session key " "encryption key: \n");		if (ecryptfs_verbosity > 0)			ecryptfs_dump_hex(session_key_encryption_key, 16);	}	if (unlikely(ecryptfs_verbosity > 0)) {		ecryptfs_printk(KERN_DEBUG, "Session key encryption key:\n");		ecryptfs_dump_hex(session_key_encryption_key, 16);	}	rc = virt_to_scatterlist(crypt_stat->key, key_rec->enc_key_size,				 &src_sg, 1);	if (rc != 1) {		ecryptfs_printk(KERN_ERR, "Error generating scatterlist "				"for crypt_stat session key; expected rc = 1; "				"got rc = [%d]. key_rec->enc_key_size = [%d]\n",				rc, key_rec->enc_key_size);		rc = -ENOMEM;		goto out;	}	rc = virt_to_scatterlist(key_rec->enc_key, key_rec->enc_key_size,				 &dst_sg, 1);	if (rc != 1) {		ecryptfs_printk(KERN_ERR, "Error generating scatterlist "				"for crypt_stat encrypted session key; "				"expected rc = 1; got rc = [%d]. "				"key_rec->enc_key_size = [%d]\n", rc,				key_rec->enc_key_size);		rc = -ENOMEM;		goto out;	}	mutex_lock(tfm_mutex);	rc = crypto_blkcipher_setkey(desc.tfm, session_key_encryption_key,				     crypt_stat->key_size);	if (rc < 0) {		mutex_unlock(tfm_mutex);		ecryptfs_printk(KERN_ERR, "Error setting key for crypto "				"context; rc = [%d]\n", rc);		goto out;	}	rc = 0;	ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n",			crypt_stat->key_size);	rc = crypto_blkcipher_encrypt(&desc, &dst_sg, &src_sg,				      (*key_rec).enc_key_size);	mutex_unlock(tfm_mutex);	if (rc) {		printk(KERN_ERR "Error encrypting; rc = [%d]\n", rc);		goto out;	}	ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n");	if (ecryptfs_verbosity > 0) {		ecryptfs_printk(KERN_DEBUG, "EFEK of size [%d]:\n",				key_rec->enc_key_size);		ecryptfs_dump_hex(key_rec->enc_key,				  key_rec->enc_key_size);	}encrypted_session_key_set:	/* This format is inspired by OpenPGP; see RFC 2440	 * packet tag 3 */	max_packet_size = (1                         /* Tag 3 identifier */			   + 3                       /* Max Tag 3 packet size */			   + 1                       /* Version */			   + 1                       /* Cipher code */			   + 1                       /* S2K specifier */			   + 1                       /* Hash identifier */			   + ECRYPTFS_SALT_SIZE      /* Salt */			   + 1                       /* Hash iterations */			   + key_rec->enc_key_size); /* Encrypted key size */	if (max_packet_size > (*remaining_bytes)) {		printk(KERN_ERR "Packet too large; need up to [%td] bytes, but "		       "there are only [%td] available\n", max_packet_size,		       (*remaining_bytes));		rc = -EINVAL;		goto out;	}	dest[(*packet_size)++] = ECRYPTFS_TAG_3_PACKET_TYPE;	/* Chop off the Tag 3 identifier(1) and Tag 3 packet size(3)	 * to get the number of octets in the actual Tag 3 packet */	rc = write_packet_length(&dest[(*packet_size)], (max_packet_size - 4),				 &packet_size_length);	if (rc) {		printk(KERN_ERR "Error generating tag 3 packet header; cannot "		       "generate packet length. rc = [%d]\n", rc);		goto out;	}	(*packet_size) += packet_size_length;	dest[(*packet_size)++] = 0x04; /* version 4 */	/* TODO: Break from RFC2440 so that arbitrary ciphers can be	 * specified with strings */	cipher_code = ecryptfs_code_for_cipher_string(crypt_stat);	if (cipher_code == 0) {		ecryptfs_printk(KERN_WARNING, "Unable to generate code for "				"cipher [%s]\n", crypt_stat->cipher);		rc = -EINVAL;		goto out;	}	dest[(*packet_size)++] = cipher_code;	dest[(*packet_size)++] = 0x03;	/* S2K */	dest[(*packet_size)++] = 0x01;	/* MD5 (TODO: parameterize) */	memcpy(&dest[(*packet_size)], auth_tok->token.password.salt,	       ECRYPTFS_SALT_SIZE);	(*packet_size) += ECRYPTFS_SALT_SIZE;	/* salt */	dest[(*packet_size)++] = 0x60;	/* hash iterations (65536) */	memcpy(&dest[(*packet_size)], key_rec->enc_key,	       key_rec->enc_key_size);	(*packet_size) += key_rec->enc_key_size;out:	if (rc)		(*packet_size) = 0;	else		(*remaining_bytes) -= (*packet_size);	return rc;}struct kmem_cache *ecryptfs_key_record_cache;/** * ecryptfs_generate_key_packet_set * @dest_base: Virtual address from which to write the key record set * @crypt_stat: The cryptographic context from which the *              authentication tokens will be retrieved * @ecryptfs_dentry: The dentry, used to retrieve the mount crypt stat *                   for the global parameters * @len: The amount written * @max: The maximum amount of data allowed to be written * * Generates a key packet set and writes it to the virtual address * passed in. * * Returns zero on success; non-zero on error. */intecryptfs_generate_key_packet_set(char *dest_base,				 struct ecryptfs_crypt_stat *crypt_stat,				 struct dentry *ecryptfs_dentry, size_t *len,				 size_t max){	struct ecryptfs_auth_tok *auth_tok;	struct ecryptfs_global_auth_tok *global_auth_tok;	struct ecryptfs_mount_crypt_stat *mount_crypt_stat =		&ecryptfs_superblock_to_private(			ecryptfs_dentry->d_sb)->mount_crypt_stat;	size_t written;	struct ecryptfs_key_record *key_rec;	struct ecryptfs_key_sig *key_sig;	int rc = 0;	(*len) = 0;	mutex_lock(&crypt_stat->keysig_list_mutex);	key_rec = kmem_cache_alloc(ecryptfs_key_record_cache, GFP_KERNEL);	if (!key_rec) {		rc = -ENOMEM;		goto out;	}	list_for_each_entry(key_sig, &crypt_stat->keysig_list,			    crypt_stat_list) {		memset(key_rec, 0, sizeof(*key_rec));		rc = ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok,							   mount_crypt_stat,							   key_sig->keysig);		if (rc) {			printk(KERN_ERR "Error attempting to get the global "			       "auth_tok; rc = [%d]\n", rc);			goto out_free;		}		if (global_auth_tok->flags & ECRYPTFS_AUTH_TOK_INVALID) {			printk(KERN_WARNING			       "Skipping invalid auth tok with sig = [%s]\n",			       global_auth_tok->sig);			continue;		}		auth_tok = global_auth_tok->global_auth_tok;		if (auth_tok->token_type == ECRYPTFS_PASSWORD) {			rc = write_tag_3_packet((dest_base + (*len)),						&max, auth_tok,						crypt_stat, key_rec,						&written);			if (rc) {				ecryptfs_printk(KERN_WARNING, "Error "						"writing tag 3 packet\n");				goto out_free;			}			(*len) += written;			/* Write auth tok signature packet */			rc = write_tag_11_packet((dest_base + (*len)), &max,						 key_rec->sig,						 ECRYPTFS_SIG_SIZE, &written);			if (rc) {				ecryptfs_printk(KERN_ERR, "Error writing "						"auth tok signature packet\n");				goto out_free;			}			(*len) += written;		} else if (auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) {			rc = write_tag_1_packet(dest_base + (*len),						&max, auth_tok,						crypt_stat, key_rec, &written);			if (rc) {				ecryptfs_printk(KERN_WARNING, "Error "						"writing tag 1 packet\n");				goto out_free;			}			(*len) += written;		} else {			ecryptfs_printk(KERN_WARNING, "Unsupported "					"authentication token type\n");			rc = -EINVAL;			goto out_free;		}	}	if (likely(max > 0)) {		dest_base[(*len)] = 0x00;	} else {		ecryptfs_printk(KERN_ERR, "Error writing boundary byte\n");		rc = -EIO;	}out_free:	kmem_cache_free(ecryptfs_key_record_cache, key_rec);out:	if (rc)		(*len) = 0;	mutex_unlock(&crypt_stat->keysig_list_mutex);	return rc;}struct kmem_cache *ecryptfs_key_sig_cache;int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig){	struct ecryptfs_key_sig *new_key_sig;	int rc = 0;	new_key_sig = kmem_cache_alloc(ecryptfs_key_sig_cache, GFP_KERNEL);	if (!new_key_sig) {		rc = -ENOMEM;		printk(KERN_ERR		       "Error allocating from ecryptfs_key_sig_cache\n");		goto out;	}	memcpy(new_key_sig->keysig, sig, ECRYPTFS_SIG_SIZE_HEX);	mutex_lock(&crypt_stat->keysig_list_mutex);	list_add(&new_key_sig->crypt_stat_list, &crypt_stat->keysig_list);	mutex_unlock(&crypt_stat->keysig_list_mutex);out:	return rc;}struct kmem_cache *ecryptfs_global_auth_tok_cache;intecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat,			     char *sig){	struct ecryptfs_global_auth_tok *new_auth_tok;	int rc = 0;	new_auth_tok = kmem_cache_zalloc(ecryptfs_global_auth_tok_cache,					GFP_KERNEL);	if (!new_auth_tok) {		rc = -ENOMEM;		printk(KERN_ERR "Error allocating from "		       "ecryptfs_global_auth_tok_cache\n");		goto out;	}	memcpy(new_auth_tok->sig, sig, ECRYPTFS_SIG_SIZE_HEX);	new_auth_tok->sig[ECRYPTFS_SIG_SIZE_HEX] = '\0';	mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex);	list_add(&new_auth_tok->mount_crypt_stat_list,		 &mount_crypt_stat->global_auth_tok_list);	mount_crypt_stat->num_global_auth_toks++;	mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex);out:	return rc;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -