Annotation of embedaddon/strongswan/src/libimcv/pts/pts_pcr.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2012 Andreas Steffen
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify it
                      6:  * under the terms of the GNU General Public License as published by the
                      7:  * Free Software Foundation; either version 2 of the License, or (at your
                      8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful, but
                     11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     13:  * for more details.
                     14:  */
                     15: 
                     16: #include "pts_pcr.h"
                     17: 
                     18: #include <utils/debug.h>
                     19: 
                     20: #include <stdarg.h>
                     21: 
                     22: typedef struct private_pts_pcr_t private_pts_pcr_t;
                     23: 
                     24: /**
                     25:  * Private data of a pts_pcr_t object.
                     26:  *
                     27:  */
                     28: struct private_pts_pcr_t {
                     29: 
                     30:        /**
                     31:         * Public pts_pcr_t interface.
                     32:         */
                     33:        pts_pcr_t public;
                     34: 
                     35:        /**
                     36:         * Shadow PCR registers
                     37:         */
                     38:        chunk_t pcrs[PTS_PCR_MAX_NUM];
                     39: 
                     40:        /**
                     41:         * Number of extended PCR registers
                     42:         */
                     43:        uint32_t pcr_count;
                     44: 
                     45:        /**
                     46:         * Highest extended PCR register
                     47:         */
                     48:        uint32_t pcr_max;
                     49: 
                     50:        /**
                     51:         * Bitmap of extended PCR registers
                     52:         */
                     53:        uint8_t pcr_select[PTS_PCR_MAX_NUM / 8];
                     54: 
                     55:        /**
                     56:         * Hasher used to extend shadow PCRs
                     57:         */
                     58:        hasher_t *hasher;
                     59: 
                     60: };
                     61: 
                     62: METHOD(pts_pcr_t, get_count, uint32_t,
                     63:        private_pts_pcr_t *this)
                     64: {
                     65:        return this->pcr_count;
                     66: }
                     67: 
                     68: METHOD(pts_pcr_t, select_pcr, bool,
                     69:        private_pts_pcr_t *this, uint32_t pcr)
                     70: {
                     71:        uint32_t i, f;
                     72: 
                     73:        if (pcr >= PTS_PCR_MAX_NUM)
                     74:        {
                     75:                DBG1(DBG_PTS, "PCR %2u: number is larger than maximum of %u",
                     76:                                           pcr, PTS_PCR_MAX_NUM-1);
                     77:                return FALSE;
                     78:        }
                     79: 
                     80:        /* Determine PCR selection flag */
                     81:        i = pcr / 8;
                     82:        f = 1 << (pcr - 8*i);
                     83: 
                     84:        /* Has this PCR already been selected? */
                     85:        if (!(this->pcr_select[i] & f))
                     86:        {
                     87:                this->pcr_select[i] |= f;
                     88:                this->pcr_max = max(this->pcr_max, pcr);
                     89:                this->pcr_count++;
                     90:        }
                     91:        return TRUE;
                     92: }
                     93: 
                     94: METHOD(pts_pcr_t, get_selection_size, size_t,
                     95:        private_pts_pcr_t *this)
                     96: {
                     97: 
                     98:        /**
                     99:         * A TPM v1.2 has 24 PCR Registers so the bitmask field length
                    100:         * used by TrouSerS is at least 3 bytes
                    101:         */
                    102:        return PTS_PCR_MAX_NUM / 8;
                    103: }
                    104: 
                    105: typedef struct {
                    106:        /** implements enumerator_t */
                    107:        enumerator_t public;
                    108:        /** current PCR */
                    109:        uint32_t pcr;
                    110:        /** back reference to parent */
                    111:        private_pts_pcr_t *pcrs;
                    112: } pcr_enumerator_t;
                    113: 
                    114: METHOD(enumerator_t, pcr_enumerator_enumerate, bool,
                    115:        pcr_enumerator_t *this, va_list args)
                    116: {
                    117:        uint32_t i, f, *pcr;
                    118: 
                    119:        VA_ARGS_VGET(args, pcr);
                    120: 
                    121:        while (this->pcr <= this->pcrs->pcr_max)
                    122:        {
                    123:                /* Determine PCR selection flag */
                    124:                i = this->pcr / 8;
                    125:                f = 1 << (this->pcr - 8*i);
                    126: 
                    127:                /* Assign current PCR to output argument and increase */
                    128:                *pcr = this->pcr++;
                    129: 
                    130:                /* return if PCR is selected */
                    131:                if (this->pcrs->pcr_select[i] & f)
                    132:                {
                    133:                        return TRUE;
                    134:                }
                    135:        }
                    136:        return FALSE;
                    137: }
                    138: 
                    139: METHOD(pts_pcr_t, create_enumerator, enumerator_t*,
                    140:        private_pts_pcr_t *this)
                    141: {
                    142:        pcr_enumerator_t *enumerator;
                    143: 
                    144:        INIT(enumerator,
                    145:                .public = {
                    146:                        .enumerate = enumerator_enumerate_default,
                    147:                        .venumerate = _pcr_enumerator_enumerate,
                    148:                        .destroy = (void*)free,
                    149:                },
                    150:                .pcrs = this,
                    151:        );
                    152: 
                    153:        return (enumerator_t*)enumerator;
                    154: }
                    155: 
                    156: METHOD(pts_pcr_t, get, chunk_t,
                    157:        private_pts_pcr_t *this, uint32_t pcr)
                    158: {
                    159:        return (pcr < PTS_PCR_MAX_NUM) ? this->pcrs[pcr] : chunk_empty;
                    160: }
                    161: 
                    162: METHOD(pts_pcr_t, set, bool,
                    163:        private_pts_pcr_t *this, uint32_t pcr, chunk_t value)
                    164: {
                    165:        if (value.len != PTS_PCR_LEN)
                    166:        {
                    167:                DBG1(DBG_PTS, "PCR %2u: value does not fit", pcr);
                    168:                return FALSE;
                    169:        }
                    170:        if (select_pcr(this, pcr))
                    171:        {
                    172:                memcpy(this->pcrs[pcr].ptr, value.ptr, PTS_PCR_LEN);
                    173:                return TRUE;
                    174:        }
                    175:        return FALSE;
                    176: }
                    177: 
                    178: METHOD(pts_pcr_t, extend, chunk_t,
                    179:        private_pts_pcr_t *this, uint32_t pcr, chunk_t measurement)
                    180: {
                    181:        if (measurement.len != PTS_PCR_LEN)
                    182:        {
                    183:                DBG1(DBG_PTS, "PCR %2u: measurement does not fit", pcr);
                    184:                return chunk_empty;
                    185:        }
                    186:        if (!select_pcr(this, pcr))
                    187:        {
                    188:                return chunk_empty;
                    189:        }
                    190:        if (!this->hasher->get_hash(this->hasher, this->pcrs[pcr] , NULL) ||
                    191:                !this->hasher->get_hash(this->hasher, measurement, this->pcrs[pcr].ptr))
                    192:        {
                    193:                DBG1(DBG_PTS, "PCR %2u: not extended due to hasher problem", pcr);
                    194:                return chunk_empty;
                    195:        }
                    196:        return this->pcrs[pcr];
                    197: }
                    198: 
                    199: METHOD(pts_pcr_t, get_composite, tpm_tss_pcr_composite_t*,
                    200:        private_pts_pcr_t *this)
                    201: {
                    202:        tpm_tss_pcr_composite_t *pcr_composite;
                    203:        enumerator_t *enumerator;
                    204:        uint16_t selection_size;
                    205:        uint32_t pcr_field_size, pcr;
                    206:        u_char *pos;
                    207: 
                    208:        selection_size = get_selection_size(this);
                    209:        pcr_field_size = this->pcr_count * PTS_PCR_LEN;
                    210: 
                    211:        INIT(pcr_composite,
                    212:                .pcr_select    = chunk_alloc(selection_size),
                    213:                .pcr_composite = chunk_alloc(pcr_field_size),
                    214:        );
                    215: 
                    216:        memcpy(pcr_composite->pcr_select.ptr, this->pcr_select, selection_size);
                    217:        pos = pcr_composite->pcr_composite.ptr;
                    218: 
                    219:        enumerator = create_enumerator(this);
                    220:        while (enumerator->enumerate(enumerator, &pcr))
                    221:        {
                    222:                memcpy(pos, this->pcrs[pcr].ptr, PTS_PCR_LEN);
                    223:                pos += PTS_PCR_LEN;
                    224:        }
                    225:        enumerator->destroy(enumerator);
                    226: 
                    227:        return pcr_composite;
                    228: }
                    229: 
                    230: METHOD(pts_pcr_t, destroy, void,
                    231:        private_pts_pcr_t *this)
                    232: {
                    233:        uint32_t i;
                    234: 
                    235:        for (i = 0; i < PTS_PCR_MAX_NUM; i++)
                    236:        {
                    237:                free(this->pcrs[i].ptr);
                    238:        }
                    239:        this->hasher->destroy(this->hasher);
                    240:        free(this);
                    241: }
                    242: 
                    243: /**
                    244:  * See header
                    245:  */
                    246: pts_pcr_t *pts_pcr_create(void)
                    247: {
                    248:        private_pts_pcr_t *this;
                    249:        hasher_t *hasher;
                    250:        uint32_t i;
                    251: 
                    252:        hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
                    253:        if (!hasher)
                    254:        {
                    255:                DBG1(DBG_PTS, "%N hasher could not be created",
                    256:                         hash_algorithm_short_names, HASH_SHA1);
                    257:                return NULL;
                    258:        }
                    259: 
                    260:        INIT(this,
                    261:                .public = {
                    262:                        .get_count = _get_count,
                    263:                        .select_pcr = _select_pcr,
                    264:                        .get_selection_size = _get_selection_size,
                    265:                        .create_enumerator = _create_enumerator,
                    266:                        .get = _get,
                    267:                        .set = _set,
                    268:                        .extend = _extend,
                    269:                        .get_composite = _get_composite,
                    270:                        .destroy = _destroy,
                    271:                },
                    272:                .hasher = hasher,
                    273:        );
                    274: 
                    275:        for (i = 0; i < PTS_PCR_MAX_NUM; i++)
                    276:        {
                    277:                this->pcrs[i] = chunk_alloc(PTS_PCR_LEN);
                    278:                memset(this->pcrs[i].ptr, 0x00, PTS_PCR_LEN);
                    279:        }
                    280: 
                    281:        return &this->public;
                    282: }
                    283: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>