Linux可信计算机制模块详细分析之核心文件分析(8)tpm.c核心代码注释(中)
/*设置TPM命令格式*/
ssize_t tpm_getcap(struct device *dev, __be32 subcap_id, cap_t *cap,
const char *desc)
{
struct tpm_cmd_t tpm_cmd;
int rc;
struct tpm_chip *chip = dev_get_drvdata(dev);
tpm_cmd.header.in = tpm_getcap_header;
if (subcap_id == CAP_VERSION_1_1 || subcap_id == CAP_VERSION_1_2) {
tpm_cmd.params.getcap_in.cap = subcap_id;
/*subcap field not necessary */
tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(0);
tpm_cmd.header.in.length -= cpu_to_be32(sizeof(__be32));
} else {
if (subcap_id == TPM_CAP_FLAG_PERM ||
subcap_id == TPM_CAP_FLAG_VOL)
tpm_cmd.params.getcap_in.cap = TPM_CAP_FLAG;
else
tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
tpm_cmd.params.getcap_in.subcap = subcap_id;
}
rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, desc);
if (!rc)
*cap = tpm_cmd.params.getcap_out.cap;
return rc;
}
/*TPM设备自检,成功返回0*/
static int tpm_continue_selftest(struct tpm_chip *chip)
{
int rc;
struct tpm_cmd_t cmd;
cmd.header.in = continue_selftest_header;
rc = transmit_cmd(chip, &cmd, CONTINUE_SELFTEST_RESULT_SIZE,
"continue selftest");
return rc;
}
/*返回tpm设备的序号,对应/dev/tpm#中#的值*/
static struct tpm_chip *tpm_chip_find_get(int chip_num)
{
struct tpm_chip *pos, *chip = NULL;
rcu_read_lock();
list_for_each_entry_rcu(pos, &tpm_chip_list, list) {
if (chip_num != TPM_ANY_NUM && chip_num != pos->dev_num)
continue;
if (try_module_get(pos->dev->driver->owner)) {
chip = pos;
break;
}
}
rcu_read_unlock();
return chip;
}
/*读取TPM设备中平台配置寄存器中的数据*/
static int __tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
{
int rc;
struct tpm_cmd_t cmd;
cmd.header.in = pcrread_header;
cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx);
rc = transmit_cmd(chip, &cmd, READ_PCR_RESULT_SIZE,
"attempting to read a pcr value");
if (rc == 0)
memcpy(res_buf, cmd.params.pcrread_out.pcr_result,
TPM_DIGEST_SIZE);
return rc;
}
/*读取TPM设备中平台配置寄存器中的数据,对__tpm_pcr_read()函数的进一步封装*/
int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf)
{
struct tpm_chip *chip;
int rc;
/*获取tpm设备序号*/
chip = tpm_chip_find_get(chip_num);
if (chip == NULL)
return -ENODEV;
/*读取pcr中的数据*/
rc = __tpm_pcr_read(chip, pcr_idx, res_buf);
tpm_chip_put(chip);
return rc;
}
/*扩充、更新平台配置寄存器pcr中的数据*/
int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
{
struct tpm_cmd_t cmd;
int rc;
struct tpm_chip *chip;
chip = tpm_chip_find_get(chip_num);
if (chip == NULL)
return -ENODEV;
cmd.header.in = pcrextend_header;
cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE);
rc = transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,
"attempting extend a PCR value");
tpm_chip_put(chip);
return rc;
}
/*12.www.qixoo.qixoo.com/在接受下次命令前,TPM设备状态自检。当检测状态成功可以接受命令时,返回0*/
int tpm_do_selftest(struct tpm_chip *chip)
{
int rc;
unsigned int loops;
unsigned int delay_msec = 1000;
unsigned long duration;
struct tpm_cmd_t cmd;
duration = tpm_calc_ordinal_duration(chip, TPM_ORD_CONTINUE_SELFTEST);
loops = jiffies_to_msecs(duration) / delay_msec;
rc = tpm_continue_selftest(chip);
/*在挂起或恢复期间,没有TPM设备驱动,可能失败返回10 (BAD_ORDINAL)或者28 (FAILEDSELFTEST)*/
if (rc)
return rc;
do {
/* 尝试读取pcr中的数据 */
cmd.header.in = pcrread_header;
cmd.params.pcrread_in.pcr_idx = cpu_to_be32(0);
rc = tpm_transmit(chip, (u8 *) &cmd, READ_PCR_RESULT_SIZE);
if (rc < TPM_HEADER_SIZE)
return -EFAULT;
rc = be32_to_cpu(cmd.header.out.return_code);
if (rc == TPM_ERR_DISABLED || rc == TPM_ERR_DEACTIVATED) {
dev_info(chip->dev, "TPM is disabled/deactivated (0x%X)\n", rc);
/*TPM状态是disabled 或 deactivated,TPM设备驱动可以继续运行,TPM设备可以接受处理命令*/
return 0;
}
if (rc != TPM_WARN_DOING_SELFTEST)
return rc;
msleep(delay_msec);
} while (--loops > 0);
return rc;
}
/*显示设定的TPM设备执行命令的时间*/
ssize_t tpm_show_durations(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip->vendor.duration[TPM_LONG] == 0)
return 0;
return sprintf(buf, "%d %d %d [%s]\n",
jiffies_to_usecs(chip->vendor.duration[TPM_SHORT]),
jiffies_to_usecs(chip->vendor.duration[TPM_MEDIUM]),
jiffies_to_usecs(chip->vendor.duration[TPM_LONG]),
chip->vendor.duration_adjusted
? "adjusted" : "original");
}
/*显示设定的超时时间值*/
ssize_t tpm_show_timeouts(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct tpm_chip *chip = dev_get_drvdata(dev);
return sprintf(buf, "%d %d %d %d [%s]\n",
jiffies_to_usecs(chip->vendor.timeout_a),
jiffies_to_usecs(chip->vendor.timeout_b),
jiffies_to_usecs(chip->vendor.timeout_c),
jiffies_to_usecs(chip->vendor.timeout_d),
chip->vendor.timeout_adjusted
? "adjusted" : "original");
}
/*取消TPM设备操作*/
ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip == NULL)
return 0;
/*调用tpm_chip结构体中vendor字段指向的tpm_vendor_specific 结构体中的cancel函数成员*/
chip->vendor.cancel(chip);
return count;
}
Linux可信计算机制模块详细分析之核心文件分析(8)tpm.c核心代码注释(中)的更多相关文章
- Yii2.0源码分析之——控制器文件分析(Controller.php)创建动作、执行动作
在Yii中,当请求一个Url的时候,首先在application中获取request信息,然后由request通过urlManager解析出route,再在Module中根据route来创建contr ...
- CI核心文件分析之基准测试类 (Benchmark.php)
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); /** * CodeIgniter * * ...
- 性能测试分析工具nmon文件分析时报错解决办法
1.使用nmon analyzer V334.xml分析数据时,如果文件过大,可以修改Analyser页签中的INTERVALS的最大值: 2.查找生成的nmon文件中包含的nan,删掉这些数据(需要 ...
- Linux强制访问控制机制模块分析之mls_type.h
2.4.2 mls_type.h 2.4.2.1文件描述 对于mls_type.h文件,其完整文件名为security/selinux/ss/mls_types.h,该文件定义了MLS策略使用的类型. ...
- Linux内核OOM机制的详细分析(转)
Linux 内核 有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了 防止内存耗尽而内核会把该进程杀掉.典 ...
- 【内核】linux内核启动流程详细分析
Linux内核启动流程 arch/arm/kernel/head-armv.S 该文件是内核最先执行的一个文件,包括内核入口ENTRY(stext)到start_kernel间的初始化代码, 主要作用 ...
- 【内核】linux内核启动流程详细分析【转】
转自:http://www.cnblogs.com/lcw/p/3337937.html Linux内核启动流程 arch/arm/kernel/head-armv.S 该文件是内核最先执行的一个文件 ...
- linux 时钟源初步分析linux kernel 时钟框架详细介绍
初步概念: 看datasheet的关于时钟与定时器的部分, FCLK供给cpu, HCLK供给AHB总线设备(存储器控制器,中断控制器.LCD控制器.DMA.USB主机控制器等), PCLK供给APB ...
- 【原创】Linux信号量机制分析
背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...
随机推荐
- 自己实现一个简易web服务器
一个web服务器是网络应用中最基础的环节. 构建需要理解三个内容: 1.http协议 2.socket类 3.服务端实现原理 1.1 HTTP http请求 一般一个http请求包括以下三个部分: 1 ...
- 自定义UITableViewCell实现左滑动多菜单功能LeftSwipe
今天愚人节,小伙们,愚人节快乐! 实现一个小功能,滑动菜单,显示隐藏的功能菜单, 先上图: 这里尝试用了下使用三个方式来实现了这个功能: 1.使用自定义UI ...
- Atitit. 项目文档目录大纲 总集合 v2
Atitit. 项目文档目录大纲 总集合 v2 -----Atitti.原有项目源码的架构,框架,配置与环境说明 v3 q511 -----Atitit.开发环境 与 工具 以及技术框架 以及 注意 ...
- 11、项目经理要阅读的书籍 - IT软件人员书籍系列文章
项目经理是负责软件项目的总体把控的角色.项目经理在项目中是一个管理者的角色,他需要对项目的9大领域进行学习,同时针对项目的范围.进度.沟通和风险进行处理,让项目能够按时保质保量的完成. 项目经理需要学 ...
- SQL中Round(),Floor(),Ceiling()函数的浅析
项目中的一个功能模块上用到了标量值函数,函数中又有ceiling()函数的用法,自己找了一些资料,对SQL中这几个函数做一个简单的记录,方便自己学习.有不足之处欢迎拍砖补充 1.round()函数遵循 ...
- 开窗函数 First_Value 和 Last_Value
在Sql server 2012里面,开窗函数丰富了许多,其中带出了2个新的函数 First_Value 和 Last Value .现在来介绍一下这2个函数的应用场景. 首先分析一下First_Va ...
- 生产环境常见的HTTP状态码列表
生产环境常见的HTTP状态码列表(List of HTTP status codes)为: 200 - OK,服务器成功返回网页 - Standard response for success ...
- 【C++】多态性(函数重载与虚函数)
多态性就是同一符号或名字在不同情况下具有不同解释的现象.多态性有两种表现形式: 编译时多态性:同一对象收到相同的消息却产生不同的函数调用,一般通过函数重载来实现,在编译时就实现了绑定,属于静态绑定. ...
- overflow:hidden与margin:0 auto之间的冲突
相对于父容器水平居中的代码margin:0 auto与overflow:hidden之间存在冲突.当这两个属性同时应用在一个DIV上时,在chrome浏览器中将无法居中.至于为啥我也不明白.
- 理解Docker(5):Docker 网络
本系列文章将介绍 Docker的相关知识: (1)Docker 安装及基本用法 (2)Docker 镜像 (3)Docker 容器的隔离性 - 使用 Linux namespace 隔离容器的运行环境 ...