-
Notifications
You must be signed in to change notification settings - Fork 4
/
tpm_buff.c
131 lines (102 loc) · 2.04 KB
/
tpm_buff.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
* Copyright (c) 2019 Apertus Solutions, LLC
*
* Author(s):
* Daniel P. Smith <[email protected]>
*
*/
#ifdef LINUX_KERNEL
#include <linux/types.h>
#include <linux/string.h>
#elif defined LINUX_USERSPACE
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#endif
#include "tpm.h"
#include "tpmbuff.h"
#include "tpm_common.h"
#define STATIC_TIS_BUFFER_SIZE 1024
#define TPM_CRB_DATA_BUFFER_OFFSET 0x80
#define TPM_CRB_DATA_BUFFER_SIZE 3966
u8 *tpmb_reserve(struct tpmbuff *b)
{
if (b->locked)
return NULL;
b->len = sizeof(struct tpm_header);
b->locked = 1;
b->data = b->head + b->len;
b->tail = b->data;
return b->head;
}
void tpmb_free(struct tpmbuff *b)
{
memset(b->head, 0, b->len);
b->len = 0;
b->locked = 0;
b->data = NULL;
b->tail = NULL;
}
u8 *tpmb_put(struct tpmbuff *b, size_t size)
{
u8 *tail = b->tail;
if ((b->len + size) > b->truesize)
return NULL; /* TODO: add overflow buffer support */
b->tail += size;
b->len += size;
return tail;
}
size_t tpmb_trim(struct tpmbuff *b, size_t size)
{
if (b->len < size)
size = b->len;
/* TODO: add overflow buffer support */
b->tail -= size;
b->len -= size;
return size;
}
size_t tpmb_size(struct tpmbuff *b)
{
return b->len;
}
static u8 tis_buff[STATIC_TIS_BUFFER_SIZE];
static struct tpmbuff tpm_buff;
struct tpmbuff *alloc_tpmbuff(enum tpm_hw_intf intf, u8 locality)
{
struct tpmbuff *b = &tpm_buff;
switch (intf) {
case TPM_TIS:
if (b->head)
goto reset;
b->head = (u8 *)&tis_buff;
b->truesize = STATIC_TIS_BUFFER_SIZE;
break;
case TPM_CRB:
b->head = (u8 *)(uintptr_t)(TPM_MMIO_BASE + (locality << 12)
+ TPM_CRB_DATA_BUFFER_OFFSET);
b->truesize = TPM_CRB_DATA_BUFFER_SIZE;
break;
default:
return NULL;
}
reset:
b->len = 0;
b->locked = 0;
b->data = NULL;
b->tail = NULL;
b->end = b->head + (b->truesize - 1);
return b;
}
void free_tpmbuff(struct tpmbuff *b, enum tpm_hw_intf intf)
{
switch (intf) {
case TPM_TIS:
b->head = NULL;
break;
case TPM_CRB:
b->head = NULL;
break;
default:
break;
}
}