~ubuntu-branches/ubuntu/jaunty/trousers/jaunty

« back to all changes in this revision

Viewing changes to src/tspi/tsp_pcr.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2008-01-23 22:03:00 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080123220300-fhtqja3c0oq0gp6z
Tags: 0.3.1-4
* Added patch from Aaron M. Ucko <ucko@debian.org> to allow trousers to
  build successfully on amd64, and presumably also other 64-bit
  architectures (Closes: #457400).
* Including udev rule for /dev/tpm from William Lima
  <wlima.amadeus@gmail.com> as suggested by David Smith <dds@google.com>
  (Closes: #459682).
* Added lintian overrides.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*
 
3
 * Licensed Materials - Property of IBM
 
4
 *
 
5
 * trousers - An open source TCG Software Stack
 
6
 *
 
7
 * (C) Copyright International Business Machines Corp. 2004-2006
 
8
 *
 
9
 */
 
10
 
 
11
 
 
12
#include <stdlib.h>
 
13
#include <stdio.h>
 
14
#include <string.h>
 
15
#include <unistd.h>
 
16
#include <sys/types.h>
 
17
#include <sys/mman.h>
 
18
#include <errno.h>
 
19
 
 
20
#include "trousers/tss.h"
 
21
#include "trousers/trousers.h"
 
22
#include "trousers_types.h"
 
23
#include "trousers_types.h"
 
24
#include "spi_utils.h"
 
25
#include "capabilities.h"
 
26
#include "tsplog.h"
 
27
#include "obj.h"
 
28
 
 
29
 
 
30
UINT16
 
31
get_num_pcrs(TSS_HCONTEXT tspContext)
 
32
{
 
33
        TSS_RESULT result;
 
34
        static UINT16 ret = 0;
 
35
        UINT32 subCap;
 
36
        UINT32 respSize;
 
37
        BYTE *resp;
 
38
 
 
39
        if (ret != 0)
 
40
                return ret;
 
41
 
 
42
        subCap = endian32(TPM_CAP_PROP_PCR);
 
43
        if ((result = TCS_API(tspContext)->GetTPMCapability(tspContext, TPM_CAP_PROPERTY,
 
44
                                                            sizeof(UINT32), (BYTE *)&subCap,
 
45
                                                            &respSize, &resp))) {
 
46
                if ((resp = (BYTE *)getenv("TSS_DEFAULT_NUM_PCRS")) == NULL)
 
47
                        return TSS_DEFAULT_NUM_PCRS;
 
48
 
 
49
                /* don't set ret here, next time we may be connected */
 
50
                return atoi((char *)resp);
 
51
        }
 
52
 
 
53
        ret = (UINT16)Decode_UINT32(resp);
 
54
        free(resp);
 
55
 
 
56
        return ret;
 
57
}
 
58
 
 
59
TSS_RESULT
 
60
pcrs_calc_composite(TPM_PCR_SELECTION *select, TPM_PCRVALUE *arrayOfPcrs, TPM_DIGEST *digestOut)
 
61
{
 
62
        UINT32 size, index;
 
63
        BYTE mask;
 
64
        BYTE hashBlob[1024];
 
65
        UINT32 numPCRs = 0;
 
66
        UINT64 offset = 0;
 
67
        UINT64 sizeOffset = 0;
 
68
 
 
69
        if (select->sizeOfSelect > 0) {
 
70
                sizeOffset = 0;
 
71
                Trspi_LoadBlob_PCR_SELECTION(&sizeOffset, hashBlob, select);
 
72
                offset = sizeOffset + 4;
 
73
 
 
74
                for (size = 0; size < select->sizeOfSelect; size++) {
 
75
                        for (index = 0, mask = 1; index < 8; index++, mask = mask << 1) {
 
76
                                if (select->pcrSelect[size] & mask) {
 
77
                                        memcpy(&hashBlob[(numPCRs * TPM_SHA1_160_HASH_LEN) + offset],
 
78
                                               arrayOfPcrs[index + (size << 3)].digest,
 
79
                                               TPM_SHA1_160_HASH_LEN);
 
80
                                        numPCRs++;
 
81
                                }
 
82
                        }
 
83
                }
 
84
 
 
85
                if (numPCRs > 0) {
 
86
                        offset += (numPCRs * TPM_SHA1_160_HASH_LEN);
 
87
                        UINT32ToArray(numPCRs * TPM_SHA1_160_HASH_LEN, &hashBlob[sizeOffset]);
 
88
 
 
89
                        return Trspi_Hash(TSS_HASH_SHA1, offset, hashBlob, digestOut->digest);
 
90
                }
 
91
        }
 
92
 
 
93
        return TSPERR(TSS_E_INTERNAL_ERROR);
 
94
}
 
95
 
 
96
TSS_RESULT
 
97
pcrs_sanity_check_selection(TSS_HCONTEXT tspContext,
 
98
                            struct tr_pcrs_obj *pcrs,
 
99
                            TPM_PCR_SELECTION *select)
 
100
{
 
101
        UINT16 num_pcrs, bytes_to_hold;
 
102
 
 
103
        if ((num_pcrs = get_num_pcrs(tspContext)) == 0)
 
104
                return TSPERR(TSS_E_INTERNAL_ERROR);
 
105
 
 
106
        bytes_to_hold = num_pcrs / 8;
 
107
 
 
108
        /* Is the current select object going to be interpretable by the TPM?
 
109
         * If the select object is of a size greater than the one the TPM
 
110
         * wants, just calculate the composite hash and let the TPM return an
 
111
         * error code to the user.  If its less than the size of the one the
 
112
         * TPM wants, add extra zero bytes until its the right size. */
 
113
        if (bytes_to_hold > select->sizeOfSelect) {
 
114
                if ((select->pcrSelect = realloc(select->pcrSelect, bytes_to_hold)) == NULL) {
 
115
                        LogError("malloc of %hu bytes failed.", bytes_to_hold);
 
116
                        return TSPERR(TSS_E_OUTOFMEMORY);
 
117
                }
 
118
                /* set the newly allocated bytes to 0 */
 
119
                memset(&select->pcrSelect[select->sizeOfSelect], 0,
 
120
                                bytes_to_hold - select->sizeOfSelect);
 
121
                select->sizeOfSelect = bytes_to_hold;
 
122
 
 
123
                /* realloc the pcr array as well */
 
124
                if ((pcrs->pcrs = realloc(pcrs->pcrs,
 
125
                                          (bytes_to_hold * 8) * TPM_SHA1_160_HASH_LEN)) == NULL) {
 
126
                        LogError("malloc of %d bytes failed.",
 
127
                                 (bytes_to_hold * 8) * TPM_SHA1_160_HASH_LEN);
 
128
                        return TSPERR(TSS_E_OUTOFMEMORY);
 
129
                }
 
130
        }
 
131
 
 
132
#ifdef TSS_DEBUG
 
133
        {
 
134
                int i;
 
135
                for (i = 0; i < select->sizeOfSelect * 8; i++) {
 
136
                        if (select->pcrSelect[i/8] & (1 << (i % 8))) {
 
137
                                LogDebug("PCR%d: Selected", i);
 
138
                                LogBlobData(APPID, TPM_SHA1_160_HASH_LEN,
 
139
                                            (unsigned char *)&pcrs->pcrs[i]);
 
140
                        } else {
 
141
                                LogDebug("PCR%d: Not Selected", i);
 
142
                        }
 
143
                }
 
144
        }
 
145
#endif
 
146
 
 
147
        return TSS_SUCCESS;
 
148
}