Skip to content
Snippets Groups Projects
tpm.c 29.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • 		     - TPM_RESPONSE_AUTH_LENGTH) > *pubkey_len)
    
    			return TPM_LIB_ERROR;
    		*pubkey_len = response_length - TPM_RESPONSE_HEADER_LENGTH
    			- TPM_RESPONSE_AUTH_LENGTH;
    		memcpy(pubkey, response + res_pubkey_offset,
    		       response_length - TPM_RESPONSE_HEADER_LENGTH
    		       - TPM_RESPONSE_AUTH_LENGTH);
    	}
    
    	return 0;
    }
    
    
    #ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
    
    u32 tpm_find_key_sha1(const u8 auth[20], const u8 pubkey_digest[20],
    		      u32 *handle)
    
    	u16 key_count;
    	u32 key_handles[10];
    	u8 buf[288];
    	u8 *ptr;
    	u32 err;
    	u8 digest[20];
    
    	size_t buf_len;
    	unsigned int i;
    
    	/* fetch list of already loaded keys in the TPM */
    	err = tpm_get_capability(TPM_CAP_HANDLE, TPM_RT_KEY, buf, sizeof(buf));
    	if (err)
    		return -1;
    	key_count = get_unaligned_be16(buf);
    	ptr = buf + 2;
    	for (i = 0; i < key_count; ++i, ptr += 4)
    		key_handles[i] = get_unaligned_be32(ptr);
    
    	/* now search a(/ the) key which we can access with the given auth */
    	for (i = 0; i < key_count; ++i) {
    		buf_len = sizeof(buf);
    		err = tpm_get_pub_key_oiap(key_handles[i], auth, buf, &buf_len);
    		if (err && err != TPM_AUTHFAIL)
    			return -1;
    		if (err)
    			continue;
    		sha1_csum(buf, buf_len, digest);
    		if (!memcmp(digest, pubkey_digest, 20)) {
    			*handle = key_handles[i];
    			return 0;
    		}
    	}
    	return 1;
    }
    #endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
    
    
    #endif /* CONFIG_TPM_AUTH_SESSIONS */
    
    u32 tpm_get_random(void *data, u32 count)
    
    		0x0, 0xc1,		/* TPM_TAG */
    		0x0, 0x0, 0x0, 0xe,	/* parameter size */
    		0x0, 0x0, 0x0, 0x46,	/* TPM_COMMAND_CODE */
    	};
    	const size_t length_offset = 10;
    	const size_t data_size_offset = 10;
    	const size_t data_offset = 14;
    
    	u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
    
    	size_t response_length = sizeof(response);
    
    
    	while (count > 0) {
    
    		u32 this_bytes = min((size_t)count,
    				     sizeof(response) - data_offset);
    		u32 err;
    
    
    		if (pack_byte_string(buf, sizeof(buf), "sd",
    				     0, command, sizeof(command),
    				     length_offset, this_bytes))
    			return TPM_LIB_ERROR;
    		err = tpm_sendrecv_command(buf, response, &response_length);
    		if (err)
    			return err;
    		if (unpack_byte_string(response, response_length, "d",
    				       data_size_offset, &data_size))
    			return TPM_LIB_ERROR;
    		if (data_size > count)
    			return TPM_LIB_ERROR;
    		if (unpack_byte_string(response, response_length, "s",
    				       data_offset, out, data_size))
    			return TPM_LIB_ERROR;
    
    		count -= data_size;
    		out += data_size;
    	}
    
    	return 0;
    }