source: trunk/packages/xen-3.1/xen-3.1/tools/firmware/rombios/32bit/tcgbios/tcgbios.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 35.5 KB
Line 
1/*
2 *  Implementation of the TCG BIOS extension according to the specification
3 *  described in
4 *  https://www.trustedcomputinggroup.org/specs/PCClient/TCG_PCClientImplementationforBIOS_1-20_1-00.pdf
5 *
6 *  This library is free software; you can redistribute it and/or
7 *  modify it under the terms of the GNU Lesser General Public
8 *  License as published by the Free Software Foundation; either
9 *  version 2 of the License, or (at your option) any later version.
10 *
11 *  This library is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 *  Lesser General Public License for more details.
15 *
16 *  You should have received a copy of the GNU Lesser General Public
17 *  License along with this library; if not, write to the Free Software
18 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 *
20 * Copyright (C) IBM Corporation, 2006
21 *
22 * Author: Stefan Berger <stefanb@us.ibm.com>
23 */
24#include "rombios_compat.h"
25#include "tpm_drivers.h"
26
27#include "tcgbios.h"
28#include "32bitprotos.h"
29#include "util.h"
30
31
32/* local structure and variables */
33struct ptti_cust {
34        uint16_t    ipblength;
35        uint16_t    reserved;
36        uint16_t    opblength;
37        uint16_t    reserved2;
38        uint8_t     tpmoperandin[18];
39} __attribute__((packed));
40
41struct ptti_cust CMD_TPM_Startup_0x01_IPB = {
42    0x8+0xc, 0x00, 4+10, 0x00,
43    { 0x00, 0xc1, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x99, 0x00, 0x01 },
44};
45
46struct ptti_cust CMD_TSC_PhysicalPresence_0x20_IPB = {
47    0x8+0xc, 0x00, 4+10, 0x00,
48    { 0x00, 0xc1, 0x00, 0x00, 0x00, 0x0c, 0x40, 0x00, 0x00, 0x0a, 0x00, 0x20 },
49};
50
51struct ptti_cust CMD_TSC_PhysicalPresence_0x08_IPB = {
52    0x8+0xc, 0x00, 4+10, 0x00,
53    { 0x00, 0xc1, 0x00, 0x00, 0x00, 0x0c, 0x40, 0x00, 0x00, 0x0a, 0x00, 0x08 },
54};
55
56struct ptti_cust CMD_TSC_PhysicalPresence_0x100_IPB = {
57    0x8+0xc, 0x00, 4+10, 0x00,
58    { 0x00, 0xc1, 0x00, 0x00, 0x00, 0x0c, 0x40, 0x00, 0x00, 0x0a, 0x01, 0x00 },
59};
60
61struct ptti_cust CMD_TSC_PhysicalPresence_0x10_IPB = {
62    0x8+0xc, 0x00, 4+10, 0x00,
63    { 0x00, 0xc1, 0x00, 0x00, 0x00, 0x0c, 0x40, 0x00, 0x00, 0x0a, 0x00, 0x10 },
64};
65
66struct ptti_cust CMD_TPM_PhysicalEnable_IPB = {
67    0x8+0xa, 0x00, 4+10, 0x00,
68    { 0x00, 0xc1, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x6f },
69};
70
71struct ptti_cust CMD_TPM_PhysicalSetDeactivated_0x00_IPB = {
72    0x8+0xb, 0x00, 4+10, 0x00,
73    { 0x00, 0xc1, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x72, 0x00 }
74};
75struct ptti_cust CMD_TPM_SHA1Start_IPB = {
76    0x8+0xa, 0x00, 4+10, 0x00,
77    { 0x00, 0xc1, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xa0 },
78};
79
80struct ptti_cust CMD_TPM_GetCap_Version_IPB = {
81    0x8+0x12, 0x00, 4+18, 0x00,
82    {0x00, 0xc1, 0x00, 0x00, 0x00, 0x12,
83     0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00 },
84};
85
86struct ptti_cust *TCG_CommandList[] = {
87        &CMD_TPM_Startup_0x01_IPB,
88        &CMD_TSC_PhysicalPresence_0x20_IPB,
89        &CMD_TSC_PhysicalPresence_0x08_IPB,
90        &CMD_TSC_PhysicalPresence_0x100_IPB,
91        &CMD_TSC_PhysicalPresence_0x10_IPB,
92        &CMD_TPM_PhysicalEnable_IPB,
93        &CMD_TPM_PhysicalSetDeactivated_0x00_IPB,
94        &CMD_TPM_SHA1Start_IPB,
95};
96
97/* local function prototypes */
98static void sha1(const unsigned char *data, uint32_t length,
99                 unsigned char *hash);
100static uint32_t TCG_ShutdownPreBootInterface(uint32_t ebx);
101static uint32_t HashAll32(struct hai *hai, unsigned char *hash,
102                          uint32_t magic, uint32_t ecx, uint32_t edx);
103static uint32_t HashLogExtendEvent32(struct hleei_short *hleei_s,
104                                     struct hleeo *hleeo,
105                                     uint32_t magic, uint32_t ecx,
106                                     uint32_t edx);
107static uint32_t HashLogEvent32(struct hlei *hlei, struct hleo *hleo,
108                               uint32_t ebx, uint32_t ecx, uint32_t edx);
109static uint32_t PassThroughToTPM32(struct pttti *pttti, struct pttto *pttto,
110                                   uint32_t magic, uint32_t ecx, uint32_t edx);
111static uint32_t MA_Transmit(unsigned char *cmdbuffer,
112                            unsigned char *respbuffer,
113                            uint32_t respbufferlen);
114
115static unsigned char *tcpa_get_lasa_last_ptr(void);
116static unsigned char *tcpa_get_lasa_base_ptr(void);
117static void tcpa_reset_acpi_log(void);
118static uint32_t tcpa_get_laml(void);
119
120
121extern struct tpm_driver tpm_drivers[];
122
123/* utility functions */
124
125static inline uint32_t bswap(uint32_t a)
126{
127        return ( ( a >> 24 ) & 0x000000ff) |
128               ( ( a >> 8  ) & 0x0000ff00) |
129               ( ( a << 8  ) & 0x00ff0000) |
130               ( ( a << 24 ) & 0xff000000);
131}
132
133/********************************************************
134  Extensions for TCG-enabled BIOS
135 *******************************************************/
136
137typedef struct {
138        struct acpi_20_tcpa *tcpa_ptr;
139        unsigned char       *lasa_last_ptr;
140        uint16_t            entry_count;
141        uint16_t            flags;
142} tcpa_acpi_t;
143
144static tcpa_acpi_t tcpa_acpi;
145
146
147/* low level driver implementation */
148static int tpm_driver_to_use = TPM_INVALID_DRIVER;
149
150static
151uint32_t MA_IsTPMPresent(void)
152{
153        uint32_t rc = 0;
154        unsigned int i;
155        for (i = 0; i < TPM_NUM_DRIVERS; i++) {
156                struct tpm_driver *td = &tpm_drivers[i];
157                if (td->probe(td->baseaddr) != 0) {
158                        tpm_driver_to_use = i;
159                        rc = 1;
160                        break;
161                }
162        }
163        return rc;
164}
165
166static
167uint32_t MA_InitTPM(uint16_t startupcode)
168{
169        uint32_t rc = 0;
170        /* low-level initialize the TPM */
171        unsigned char command[sizeof(CMD_TPM_Startup_0x01_IPB.tpmoperandin)];
172        unsigned char response[10];
173        uint32_t response_size = sizeof(response);
174
175        memcpy(command,
176               CMD_TPM_Startup_0x01_IPB.tpmoperandin,
177               sizeof(CMD_TPM_Startup_0x01_IPB.tpmoperandin));
178        command[10] = (startupcode >> 8) & 0xff;
179        command[11] = (startupcode >> 0) & 0xff;
180        rc = MA_Transmit(command, response, response_size);
181
182        return rc;
183}
184
185static
186uint32_t MA_Transmit(unsigned char *cmdbuffer, unsigned char *respbuffer,
187                     uint32_t respbufferlen)
188{
189        uint32_t rc = 0;
190        uint32_t irc;
191        struct tpm_driver *td;
192
193        if (tpm_driver_to_use == TPM_INVALID_DRIVER)
194                return TCG_FATAL_COM_ERROR;
195
196        td = &tpm_drivers[tpm_driver_to_use];
197
198        if (rc == 0) {
199                irc = td->activate(td->baseaddr);
200                if (irc == 0) {
201                        /* tpm could not be activated */
202                        rc = TCG_FATAL_COM_ERROR;
203                }
204        }
205
206        if (rc == 0) {
207                uint32_t *tmp = (uint32_t *)&cmdbuffer[2];
208                uint32_t len = bswap(*tmp);
209                irc = td->senddata(td->baseaddr,
210                                   cmdbuffer,
211                                   len);
212                if (irc != 0) {
213                        rc = TCG_FATAL_COM_ERROR;
214                }
215        }
216
217        if (rc == 0) {
218                irc = td->waitdatavalid(td->baseaddr);
219                if (irc != 0) {
220                        rc = TCG_FATAL_COM_ERROR;
221                }
222        }
223
224        if (rc == 0) {
225                irc = td->waitrespready(td->baseaddr, 2000);
226                if (irc != 0) {
227                        rc = TCG_FATAL_COM_ERROR;
228                }
229        }
230
231        if (rc == 0) {
232                irc = td->readresp(td->baseaddr,
233                                   respbuffer,
234                                   respbufferlen);
235                if (irc != 0) {
236                        rc = TCG_FATAL_COM_ERROR;
237                }
238        }
239
240        if (rc == 0) {
241                irc = td->ready(td->baseaddr);
242        }
243
244        return rc;
245}
246
247
248static
249uint8_t acpi_validate_entry(struct acpi_header *hdr)
250{
251        uint8_t sum = 0;
252        unsigned int length = hdr->length;
253        unsigned int ctr;
254        unsigned char *addr = (unsigned char *)hdr;
255
256        for (ctr = 0; ctr < length; ctr++)
257                sum += addr[ctr];
258
259        return sum;
260}
261
262
263void tcpa_acpi_init(void)
264{
265        struct acpi_20_rsdt *rsdt;
266        uint32_t length;
267        struct acpi_20_tcpa *tcpa = (void *)0;
268        uint16_t found = 0;
269        uint16_t rsdp_off;
270        uint16_t off;
271        struct acpi_20_rsdp *rsdp = (void *)0;
272
273        if (MA_IsTPMPresent() == 0) {
274                return;
275        }
276
277        /* scan memory in steps of  16 bytes in the ACPI_SEGMENT segment */
278        found = 0;
279        for (rsdp_off = 0; rsdp_off < 0xfff0; rsdp_off += 0x10) {
280                char *_rsdp = (char *)(ACPI_SEGMENT << 4);
281                /* check for expected string */
282                if (!strncmp( &_rsdp[rsdp_off], "RSD PTR ", 8)) {
283                        found = 1;
284                        rsdp = (struct acpi_20_rsdp *)&_rsdp[rsdp_off];
285                        break;
286                }
287        }
288
289        if (rsdp) {
290                uint32_t ctr = 0;
291                /* get RSDT from RSDP */
292                rsdt   = (struct acpi_20_rsdt *)rsdp->rsdt_address;
293                length = rsdt->header.length;
294                off = 36;
295                while ((off + 3) < length) {
296                        /* try all pointers to structures */
297                        tcpa = (struct acpi_20_tcpa *)rsdt->entry[ctr];
298                        /* valid TCPA ACPI table ? */
299                        if (ACPI_2_0_TCPA_SIGNATURE == tcpa->header.signature
300                            && acpi_validate_entry(&tcpa->header) == 0) {
301                                found = 1;
302                                break;
303                        }
304                        off += 4;
305                        ctr++;
306                }
307        }
308
309        if (found == 0) {
310                printf("TCPA ACPI was NOT found!\n");
311                tcpa = 0;
312        }
313
314        tcpa_acpi.tcpa_ptr = tcpa;
315        tcpa_acpi.lasa_last_ptr = 0;
316        tcpa_acpi.entry_count = 0;
317        tcpa_acpi.flags = 0;
318        tcpa_reset_acpi_log();
319}
320
321/* clear the ACPI log */
322static void tcpa_reset_acpi_log(void)
323{
324        unsigned char *lasa = tcpa_get_lasa_base_ptr();
325        if (lasa)
326                memset(lasa, 0x0, tcpa_get_laml());
327}
328
329
330uint32_t tcpa_extend_acpi_log(uint32_t entry_ptr)
331{
332        uint32_t res = 0;
333        unsigned char *lasa_last = tcpa_get_lasa_last_ptr();
334        unsigned char *lasa_base = tcpa_get_lasa_base_ptr();
335        uint32_t size;
336        uint16_t entry_count = tcpa_acpi.entry_count;
337        struct pcpes *pcpes = (struct pcpes *)entry_ptr;
338
339        if (lasa_last == 0) {
340                lasa_last = lasa_base;
341        } else {
342                struct pcpes *pcpes = (struct pcpes *)lasa_last;
343                /* skip the last entry in the log */
344                size = pcpes->eventdatasize;
345                size += 32;
346                lasa_last += size;
347        }
348
349        if (lasa_last == 0) {
350                res = ((uint32_t)TCG_PC_LOGOVERFLOW << 16);
351        }
352
353        if (res == 0) {
354                uint32_t laml = tcpa_get_laml();
355                size = pcpes->eventdatasize;
356                size += 32;
357                if ((lasa_last + size - lasa_base) > laml) {
358                        res = (TCG_PC_LOGOVERFLOW << 16);
359                }
360        }
361
362        if (res == 0) {
363                /* copy the log entry into the ACPI log */
364                memcpy((char *)lasa_last, (char *)entry_ptr, size);
365                /*
366                 * update the pointers and entry counter that were modified
367                 * due to the new entry in the log
368                 */
369                tcpa_acpi.lasa_last_ptr = lasa_last;
370                entry_count++;
371                tcpa_acpi.entry_count = entry_count;
372
373                res = entry_count;
374        }
375        return res;
376}
377
378static
379unsigned char *tcpa_get_lasa_last_ptr(void)
380{
381        return tcpa_acpi.lasa_last_ptr;
382}
383
384static
385unsigned char *tcpa_get_lasa_base_ptr(void)
386{
387        unsigned char *lasa = 0;
388        struct acpi_20_tcpa *tcpa = tcpa_acpi.tcpa_ptr;
389        if (tcpa != 0) {
390                uint32_t class = tcpa->platform_class;
391                if (class == TCPA_ACPI_CLASS_CLIENT) {
392                        /* client type */
393                        lasa = (unsigned char *)(long)tcpa->u.client.lasa;
394                } else if (class == TCPA_ACPI_CLASS_SERVER) {
395                        /* server type */
396                        lasa = (unsigned char *)(long)tcpa->u.server.lasa;
397                }
398        }
399        return lasa;
400}
401
402static
403uint32_t tcpa_get_laml(void)
404{
405        uint32_t laml = 0;
406        struct acpi_20_tcpa *tcpa = tcpa_acpi.tcpa_ptr;
407        if (tcpa != 0) {
408                uint32_t class = tcpa->platform_class;
409                if (class == TCPA_ACPI_CLASS_CLIENT) {
410                        /* client type */
411                        laml = tcpa->u.client.laml;
412                } else if (class == TCPA_ACPI_CLASS_SERVER) {
413                        laml = tcpa->u.server.laml;
414                }
415        }
416        return laml;
417}
418
419
420
421/*
422 * Add a measurement to the log; the data at data_seg:data/length are
423 * appended to the TCG_PCClientPCREventStruct
424 *
425 * Input parameters:
426 *  pcrIndex   : which PCR to extend
427 *  event_type : type of event; specs 10.4.1
428 *  event_id   : (unused)
429 *  data       : pointer to the data (i.e., string) to be added to the log
430 *  length     : length of the data
431 */
432static uint16_t
433tcpa_add_measurement_to_log(uint32_t pcrIndex,
434                            uint32_t event_type,
435                            uint32_t event_id,
436                            const char *data_ptr,
437                            uint32_t length)
438{
439        uint32_t rc = 0;
440        struct hleei_short hleei;
441        struct hleeo hleeo;
442        uint8_t _pcpes[32+400];
443        struct pcpes *pcpes = (struct pcpes *)_pcpes;
444        uint8_t *data = (uint8_t *)data_ptr;
445
446        if (length < sizeof(_pcpes)-32) {
447                memset(pcpes, 0x0, 32);
448                pcpes->pcrindex   = pcrIndex;
449                pcpes->eventtype = event_type;
450                pcpes->eventdatasize = length;
451                memcpy(&_pcpes[32], data, length);
452
453                hleei.ipblength = 0x18;
454                hleei.reserved  = 0x0;
455                hleei.hashdataptr = (uint32_t)&_pcpes[32];
456                hleei.hashdatalen = length;
457                hleei.pcrindex    = pcrIndex;
458                hleei.logdataptr  = (uint32_t)_pcpes;
459                hleei.logdatalen  = length + 32;
460                rc = HashLogExtendEvent32(&hleei,
461                                          &hleeo,
462                                          TCG_MAGIC,
463                                          0x0,
464                                          0x0);
465        } else {
466                rc = (TCG_PC_TPMERROR |
467                      ((uint32_t)TCG_GENERAL_ERROR << 16));
468        }
469
470        return rc;
471}
472
473static
474uint16_t tcpa_add_pcpes_to_log(struct pcpes *pcpes)
475{
476        uint32_t rc = 0;
477        struct hleei_short hleei;
478        struct hleeo hleeo;
479
480        hleei.ipblength = 0x18;
481        hleei.reserved  = 0x0;
482        hleei.hashdataptr = 0;
483        hleei.hashdatalen = 0;
484        hleei.pcrindex    = pcpes->pcrindex;
485        hleei.logdataptr  = (uint32_t)pcpes;
486        hleei.logdatalen  = sizeof(pcpes);
487
488        rc = HashLogExtendEvent32(&hleei,
489                                  &hleeo,
490                                  TCG_MAGIC,
491                                  0x0,
492                                  0x0);
493
494        return rc;
495}
496
497
498/*
499 * Add a measurement to the log; further description of the data
500 * that are to be hashed are NOT appended to the TCG_PCClientPCREventStruc.
501 * Input parameters:
502 *  pcrIndex   : PCR to extend
503 *  event_type : type of event; specs 10.4.1
504 *  ptr        : 32 bit pointer to the data to be hashed
505 *  length     : length of the data to be hashed
506 *
507 * Returns lower 16 bit of return code of TCG_HashLogExtendEvent. '0' means
508 * success, otherwise an error is indicated.
509 */
510static
511uint16_t tcpa_add_measurement_to_log_simple(uint32_t pcrIndex,
512                                            uint16_t event_type,
513                                            uint8_t *ptr, uint32_t length)
514{
515        uint32_t rc = 0;
516        struct hleei_short hleei;
517        struct hleeo hleeo;
518        struct pcpes pcpes;
519
520        memset(&pcpes, 0x0, sizeof(pcpes));
521        pcpes.pcrindex = pcrIndex;
522        pcpes.eventtype = event_type;
523        pcpes.eventdatasize = length;
524
525        hleei.ipblength = 0x18;
526        hleei.reserved  = 0x0;
527        hleei.hashdataptr = (uint32_t)ptr;
528        hleei.hashdatalen = length;
529        hleei.pcrindex = pcrIndex;
530        hleei.logdataptr = (uint32_t)&pcpes;
531        hleei.logdatalen = 32;
532
533        rc = HashLogExtendEvent32(&hleei,
534                                  &hleeo,
535                                  TCG_MAGIC,
536                                  0x0,
537                                  0x0);
538        return rc;
539}
540
541/* table of event types according to 10.4.1 / table 11 */
542static const char ev_action[][23] = {
543  /*  0 */ "Calling INT 19h",
544           "Returned INT 19h",
545           "Returned via INT 18h",
546           "",
547           "",
548  /*  5 */ "",
549           "",
550           "",
551           "",
552           "",
553  /* 10 */ "",
554           "",
555           "",
556           "",
557           "Start Option ROM Scan"
558};
559
560
561static char evt_separator[] = "---------------";
562static char wake_event_1[]    = "Wake Event 1";
563
564
565/*
566 * Add a measurement to the list of measurements
567 * pcrIndex   : PCR to be extended
568 * event_type : type of event; specs 10.4.1
569 * data       : additional parameter; used as parameter for 10.4.3
570 *              'action index'
571 */
572void tcpa_add_measurement(uint32_t pcrIndex,
573                          uint16_t event_type,
574                          uint32_t data)
575{
576        const char *string;
577
578        switch (event_type) {
579        case EV_SEPARATOR:
580                tcpa_add_measurement_to_log(pcrIndex,
581                                            event_type,
582                                            0,
583                                            evt_separator,
584                                            strlen(evt_separator));
585        break;
586        case EV_ACTION:
587                string = ev_action[data /* event_id */];
588                tcpa_add_measurement_to_log(pcrIndex,
589                                            event_type,
590                                            data,
591                                            string,
592                                            strlen(string));
593
594        break;
595        }
596}
597
598
599/*
600 * Add measurement to log about call of int 19h
601 */
602void tcpa_calling_int19h()
603{
604        tcpa_add_measurement(4, EV_ACTION, 0);
605}
606
607/*
608 * Add measurement to log about retuning from int 19h
609 */
610void tcpa_returned_int19h()
611{
612        tcpa_add_measurement(4, EV_ACTION, 1);
613}
614
615/*
616 * Add event separators for PCRs 0 to 7; specs 8.2.3
617 */
618void tcpa_add_event_separators()
619{
620        uint32_t pcrIndex = 0;
621        while (pcrIndex <= 7) {
622                tcpa_add_measurement(pcrIndex, EV_SEPARATOR, 0);
623                pcrIndex ++;
624        }
625}
626
627
628/*
629 * Add a wake event to the log
630 */
631void tcpa_wake_event()
632{
633        tcpa_add_measurement_to_log(6,
634                                    EV_ACTION,
635                                    10,
636                                    wake_event_1,
637                                    strlen(wake_event_1));
638}
639
640/*
641 * add the boot device to the measurement log
642 */
643void tcpa_add_bootdevice(uint32_t bootcd, uint32_t bootdrv)
644{
645        char *string;
646        if (bootcd == 0) {
647                if (bootdrv == 0) {
648                        string = "Booting BCV device 00h (Floppy)";
649                } else if (bootdrv == 0x80) {
650                        string = "Booting BCV device 80h (HDD)";
651                } else {
652                        string = "Booting unknown device";
653                }
654        } else {
655                string = "Booting from CD ROM device";
656        }
657        tcpa_add_measurement_to_log(4, 5, 0,
658                                    string, strlen(string));
659}
660
661/*
662 * Add measurement to the log about option rom scan
663 * 10.4.3 : action 14
664 */
665void tcpa_start_option_rom_scan()
666{
667        tcpa_add_measurement(2, EV_ACTION, 14);
668}
669
670
671/*
672 * Add measurement to the log about an option rom
673 */
674void tcpa_option_rom(uint32_t seg)
675{
676        uint32_t len = read_byte(seg, 2) << 9;
677        uint8_t *addr = (uint8_t *)ADDR_FROM_SEG_OFF(seg,0);
678        char append[32]; /* TCG_PCClientTaggedEventStruct and
679                             OptionROMExecuteStructure; specs 10.4.2.1 */
680        struct hai hai;   /* HashAll Input Block; specs 12.10 */
681
682        memset(append, 0x0, sizeof(append));
683
684        append[0] = 7; /* Option ROM Execute */
685        append[4] = 24;/* size of OptionROMExecute Structure */
686        /* leave the rest to '0' */
687
688        /* 12.10 table 21 */
689        hai.ipblength   = 0x10;
690        hai.reserved    = 0;
691        hai.hashdataptr = (uint32_t)addr;
692        hai.hashdatalen = len;
693        hai.algorithmid = TPM_ALG_SHA;
694
695        HashAll32(&hai,
696                  (unsigned char *)append+12,
697                  TCG_MAGIC,
698                  0,
699                  0);
700
701        tcpa_add_measurement_to_log(2,
702                                    EV_EVENT_TAG,
703                                    0,
704                                    append,
705                                    32);
706}
707
708/*
709 * Add a measurement to the log in support of 8.2.5.3
710 * Creates two log entries
711 *
712 * Input parameter:
713 *  seg    : segment where the IPL data are located
714 */
715void tcpa_ipl(Bit32u seg)
716{
717        /* specs: 8.2.5.3 */
718        uint8_t *addr = (uint8_t *)ADDR_FROM_SEG_OFF(seg,0);
719        /* equivalent to: dd if=/dev/hda ibs=1 count=440 | sha1sum */
720        tcpa_add_measurement_to_log_simple(4,
721                                           EV_IPL,
722                                           addr,
723                                           0x1b8);
724        /* equivalent to: dd if=/dev/hda ibs=1 count=72 skip=440 | sha1sum */
725        tcpa_add_measurement_to_log_simple(5,
726                                           EV_IPL_PARTITION_DATA,
727                                           addr + 0x1b8,
728                                           0x48);
729}
730
731void tcpa_measure_post(Bit32u from, Bit32u to)
732{
733        struct pcpes pcpes; /* PCClientPCREventStruc */
734        int len = to - from;
735        memset(&pcpes, 0x0, sizeof(pcpes));
736
737        if (len > 0) {
738                sha1((unsigned char *)from,
739                     to-from,
740                     (unsigned char *)&pcpes.digest);
741
742                pcpes.eventtype = EV_POST_CODE;
743                pcpes.eventdatasize = 0;
744                pcpes.pcrindex = 0;
745                tcpa_add_pcpes_to_log(&pcpes);
746        }
747}
748
749static
750uint32_t SendCommand32(uint32_t idx, struct pttto *pttto, uint32_t size_ptto)
751{
752        uint32_t rc = 0;
753        struct pttti *pttti = (struct pttti *)TCG_CommandList[idx];
754        uint8_t _pttto[30];
755
756        if (size_ptto > 0 && size_ptto < 14) {
757                rc = (TCG_PC_TPMERROR |
758                      ((uint32_t)TCG_INVALID_INPUT_PARA << 16));
759        }
760
761        if (rc == 0) {
762                if (size_ptto == 0) {
763                        pttto = (struct pttto *)_pttto;
764                        size_ptto = sizeof(_pttto);
765                }
766                pttti->opblength = size_ptto;
767        }
768
769        if (rc == 0) {
770                if (pttti->opblength > size_ptto) {
771                        rc = (TCG_PC_TPMERROR |
772                              ((uint32_t)TCG_OUTPUT_BUFFER_TOO_SHORT << 16));
773                }
774        }
775
776        if (rc == 0) {
777                rc = PassThroughToTPM32(pttti,
778                                        pttto,
779                                        TCG_MAGIC,
780                                        0x0,
781                                        0x0);
782        }
783
784        return rc;
785}
786
787
788uint32_t tcpa_initialize_tpm(uint32_t physpres)
789{
790        uint32_t rc = 0;
791        uint8_t _pttto[40];
792        struct pttto *pttto = (struct pttto *)_pttto;
793        uint32_t pttto_size = sizeof(_pttto);
794
795        if (rc == 0) {
796                rc = SendCommand32(IDX_CMD_TPM_Startup_0x01, pttto,
797                                   pttto_size);
798        }
799
800        if (rc == 0 && physpres != 0) {
801                rc = SendCommand32(IDX_CMD_TSC_PhysicalPresence_0x20,
802                                   pttto, pttto_size);
803        }
804
805        if (rc == 0 && physpres != 0) {
806                rc = SendCommand32(IDX_CMD_TSC_PhysicalPresence_0x08,
807                                   pttto, pttto_size);
808        }
809
810        if (rc == 0 && physpres != 0) {
811                rc = SendCommand32(IDX_CMD_TPM_PhysicalEnable,
812                                   pttto, pttto_size);
813        }
814
815        if (rc == 0 && physpres != 0) {
816                rc = SendCommand32(IDX_CMD_TPM_PhysicalSetDeactivated_0x00,
817                                   pttto, pttto_size);
818        }
819
820        if (rc == 0) {
821                rc = SendCommand32(IDX_CMD_TSC_PhysicalPresence_0x100,
822                                   pttto, pttto_size);
823        }
824
825        if (rc == 0) {
826                rc = SendCommand32(IDX_CMD_TSC_PhysicalPresence_0x10,
827                                   pttto, pttto_size);
828        }
829        return rc;
830}
831
832
833uint16_t TCG_IsShutdownPreBootInterface(void)
834{
835        return tcpa_acpi.flags & STATUS_FLAG_SHUTDOWN;
836}
837
838
839static
840uint32_t _TCG_TPM_Extend(unsigned char *hash, uint32_t pcrindex)
841{
842        uint32_t rc;
843        uint8_t _pttti[8+34];
844        uint8_t _pttto[4+30];
845        struct pttti *pttti = (struct pttti*)&_pttti;
846        struct pttto *pttto = (struct pttto*)&_pttto;
847
848        pttti->ipblength = 8 + 34;
849        pttti->reserved  = 0;
850        pttti->opblength = 4 + 30;
851        pttti->reserved2 = 0;
852
853        _pttti[8 + 0] = 0x0;
854        _pttti[8 + 1] = 0xc1;
855        *(uint32_t *)&_pttti[8 + 2] = bswap(34);
856        *(uint32_t *)&_pttti[8 + 6] = bswap(0x14);
857        *(uint32_t *)&_pttti[8 + 10]= bswap(pcrindex);
858        memcpy(&_pttti[8+14], hash, 20);
859
860        rc = PassThroughToTPM32(pttti,
861                                pttto,
862                                TCG_MAGIC,
863                                0x0,
864                                0x0);
865        /* sanity check of result */
866        if (_pttto[4] != 0x00 || _pttto[5] != 0xc4) {
867                rc = (TCG_PC_TPMERROR |
868                      ((uint32_t)TCG_FATAL_COM_ERROR << 16));
869        }
870
871        if (rc != 0) {
872                /*
873                   Invalidate the log since system did not process this
874                   extend properly.
875                 */
876                tcpa_reset_acpi_log();
877                memset(&tcpa_acpi, 0x0, sizeof(tcpa_acpi));
878                TCG_ShutdownPreBootInterface(0);
879        }
880        return rc;
881}
882
883
884static
885uint32_t HashLogExtendEvent32(struct hleei_short *hleei_s, struct hleeo *hleeo,
886                              uint32_t magic, uint32_t ecx, uint32_t edx)
887{
888        uint32_t rc = 0;
889        uint16_t size;
890        struct hlei hlei ; /* HashLogEventInput block */
891        struct hleo hleo;  /* HashLogEventOutput block */
892        struct hleei_long *hleei_l = (struct hleei_long *)hleei_s;
893        int sh;
894        uint32_t logdataptr;
895
896        if (TCG_IsShutdownPreBootInterface() != 0) {
897                rc = (TCG_PC_TPMERROR |
898                      ((uint32_t)TCG_INTERFACE_SHUTDOWN << 16));
899        }
900
901        if (rc == 0) {
902                /* short or long version? */
903                size = hleei_s->ipblength;
904                if (size == 0x18) {
905                        /* short */
906                        sh = 1;
907                } else if (size == 0x1c) {
908                        /* long */
909                        sh = 0;
910                } else {
911                        /* bad input block */
912                        rc = TCG_PC_TPMERROR |
913                             ((uint32_t)(TCG_INVALID_ACCESS_REQUEST << 16));
914                }
915        }
916
917        if (rc == 0) {
918                uint32_t hashdataptr;
919                uint32_t hashdatalen;
920                uint32_t pcrindex;
921                uint32_t logeventtype;
922                uint32_t logdatalen;
923                uint32_t eventnumber;
924                uint8_t hash[20];
925                struct pcpes *pcpes;
926
927                hashdataptr = hleei_s->hashdataptr;
928                hashdatalen = hleei_s->hashdatalen;
929                pcrindex    = hleei_s->pcrindex;
930                if (sh) {
931                        logdataptr = hleei_s->logdataptr;
932                        logdatalen = hleei_s->logdatalen;
933                } else {
934                        logdataptr = hleei_l->logdataptr;
935                        logdatalen = hleei_l->logdatalen;
936                }
937
938                pcpes = (struct pcpes *)logdataptr;
939                logeventtype = pcpes->eventtype;
940
941                /* fill out HashLogEventInput block 'hlie' */
942                hlei.ipblength = 0x1c;
943                hlei.reserved = 0;
944                hlei.hashdataptr = hashdataptr;
945                hlei.hashdatalen = hashdatalen;
946                hlei.pcrindex    = pcrindex;
947                hlei.logeventtype= logeventtype;
948                hlei.logdataptr  = logdataptr;
949                hlei.logdatalen  = logdatalen;
950
951                rc = HashLogEvent32(&hlei,
952                                    &hleo,
953                                    TCG_MAGIC,
954                                    0x0,
955                                    0x0);
956                eventnumber = hleo.eventnumber;
957
958                hleeo->opblength = 8 + 20;
959                hleeo->reserved  = 0;
960                hleeo->eventnumber = eventnumber;
961
962                memcpy(hash, (unsigned char *)logdataptr + 0x8, 20);
963                _TCG_TPM_Extend(hash, pcrindex);
964        }
965
966        if (rc != 0) {
967                hleeo->opblength = 4;
968                hleeo->reserved  = 0;
969        }
970        return rc;
971
972}
973
974
975static
976uint32_t PassThroughToTPM32(struct pttti *pttti, struct pttto *pttto,
977                            uint32_t magic, uint32_t ecx, uint32_t edx)
978{
979        uint32_t rc = 0;
980        uint8_t *cmd32;
981        uint32_t resbuflen = 0;
982
983        if (TCG_IsShutdownPreBootInterface() != 0) {
984                rc = (TCG_PC_TPMERROR |
985                      ((uint32_t)TCG_INTERFACE_SHUTDOWN << 16));
986        }
987
988        if (rc == 0) {
989                if (pttti->ipblength < 0x8 + 10) {
990                        rc = TCG_PC_TPMERROR |
991                             ((uint32_t)(TCG_INVALID_ACCESS_REQUEST << 16));
992                }
993        }
994
995        if (rc == 0) {
996                if (pttti->opblength < 0x4) {
997                        rc = TCG_PC_TPMERROR |
998                             ((uint32_t)(TCG_INVALID_ACCESS_REQUEST << 16));
999                }
1000        }
1001
1002        if (rc == 0) {
1003                uint8_t *resbuf32;
1004
1005                cmd32 = &pttti->tpmoperandin[0];
1006                resbuflen = pttti->opblength - 4;
1007                resbuf32  = &pttto->tpmoperandout[0];
1008
1009                rc = MA_Transmit(cmd32, resbuf32, resbuflen);
1010        }
1011
1012        if (rc == 0) {
1013                pttto->opblength = resbuflen+4;
1014                pttto->reserved  = 0;
1015        }
1016
1017        if (rc != 0) {
1018                pttto->opblength = 0;
1019                pttto->reserved = 0;
1020        }
1021
1022        return rc;
1023}
1024
1025
1026static
1027uint32_t TCG_ShutdownPreBootInterface(uint32_t ebx)
1028{
1029        uint32_t rc = 0;
1030        if (TCG_IsShutdownPreBootInterface() == 0) {
1031                tcpa_acpi.flags |= STATUS_FLAG_SHUTDOWN;
1032        } else {
1033                rc = (TCG_PC_TPMERROR |
1034                      ((uint32_t)TCG_INTERFACE_SHUTDOWN << 16));
1035        }
1036        return rc;
1037}
1038
1039
1040static
1041uint32_t HashLogEvent32(struct hlei *hlei, struct hleo *hleo,
1042                        uint32_t ebx, uint32_t ecx, uint32_t edx)
1043{
1044        uint32_t rc = 0;
1045        uint16_t size;
1046        uint32_t logdataptr;
1047        uint32_t logdatalen;
1048        uint32_t hashdataptr;
1049        uint32_t hashdatalen;
1050
1051        if (TCG_IsShutdownPreBootInterface() != 0) {
1052                rc = (TCG_PC_TPMERROR |
1053                      ((uint32_t)TCG_INTERFACE_SHUTDOWN << 16));
1054        }
1055
1056        if (rc == 0) {
1057                size = hlei->ipblength;
1058                if (size != 0x1c) {
1059                        rc = (TCG_PC_TPMERROR |
1060                              ((uint32_t)TCG_INVALID_ACCESS_REQUEST << 16));
1061                }
1062        }
1063
1064        if (rc == 0) {
1065                struct pcpes *pcpes;
1066                logdataptr = hlei->logdataptr;
1067                logdatalen = hlei->logdatalen;
1068                pcpes = (struct pcpes *)logdataptr;
1069                if (pcpes->pcrindex != hlei->pcrindex) {
1070                        rc = (TCG_PC_TPMERROR |
1071                              ((uint32_t)TCG_INVALID_ACCESS_REQUEST << 16));
1072                }
1073        }
1074
1075        if (rc == 0) {
1076                struct pcpes *pcpes= (struct pcpes *)logdataptr;
1077                if (pcpes->eventtype != hlei->logeventtype) {
1078                        rc = (TCG_PC_TPMERROR |
1079                              ((uint32_t)TCG_INVALID_ACCESS_REQUEST << 16));
1080                }
1081        }
1082
1083        if (rc == 0) {
1084                uint32_t entry;
1085                hashdataptr = hlei->hashdataptr;
1086                hashdatalen = hlei->hashdatalen;
1087
1088                if ((hashdataptr != 0) | (hashdatalen != 0)) {
1089                        uint8_t hash[20];
1090                        struct hai hai; /* HashAll Input Block */
1091                        hai.ipblength = 0x10;
1092                        hai.reserved  = 0x0;
1093                        hai.hashdataptr = hashdataptr;
1094                        hai.hashdatalen = hashdatalen;
1095                        hai.algorithmid = TPM_ALG_SHA;
1096                        rc = HashAll32(&hai,
1097                                       hash,
1098                                       TCG_MAGIC,
1099                                       0x0,
1100                                       0x0);
1101
1102                        if (rc == 0) {
1103                                /* hashing was done ok */
1104                                memcpy((unsigned char *)logdataptr + 8,
1105                                       hash,
1106                                       20);
1107                        }
1108                }
1109
1110                if (rc == 0) {
1111                        /* extend the log with this event */
1112                        entry = tcpa_extend_acpi_log(logdataptr);
1113                        if ((uint16_t)entry == 0) {
1114                                /* upper 16 bits hold error code */
1115                                rc = (entry >> 16);
1116                        }
1117                }
1118
1119                if (rc == 0) {
1120                        /* updating the log was fine */
1121                        hleo->opblength = 8;
1122                        hleo->reserved  = 0;
1123                        hleo->eventnumber = entry;
1124                }
1125        }
1126
1127        if (rc != 0) {
1128                hleo->opblength = 2;
1129                hleo->reserved = 0;
1130        }
1131
1132        return rc;
1133}
1134
1135static
1136uint32_t HashAll32(struct hai *hai, unsigned char *hash,
1137                   uint32_t magic, uint32_t ecx, uint32_t edx)
1138{
1139        uint32_t rc = 0;
1140
1141        if (TCG_IsShutdownPreBootInterface() != 0) {
1142                rc = (TCG_PC_TPMERROR |
1143                      ((uint32_t)TCG_INTERFACE_SHUTDOWN << 16));
1144        }
1145
1146        if (rc == 0) {
1147                if (hai->ipblength != 0x10) {
1148                        rc = (TCG_PC_TPMERROR |
1149                              ((uint32_t)TCG_INVALID_ACCESS_REQUEST << 16));
1150                }
1151        }
1152
1153        if (rc == 0) {
1154                if (hai->algorithmid != TPM_ALG_SHA) {
1155                        rc = (TCG_PC_TPMERROR |
1156                             ((uint32_t)TCG_INVALID_ACCESS_REQUEST << 16));
1157                }
1158        }
1159
1160        if (rc == 0) {
1161                uint8_t *hashdataptr32;
1162                uint32_t hashdatalen32;
1163
1164                hashdataptr32 = (uint8_t *)hai->hashdataptr;
1165                hashdatalen32 = hai->hashdatalen;
1166
1167                sha1(hashdataptr32,
1168                     hashdatalen32,
1169                     hash);
1170        }
1171
1172        return rc;
1173}
1174
1175
1176static
1177uint32_t TSS32(struct ti *ti, struct to *to,
1178               uint32_t ebx, uint32_t ecx, uint32_t edx)
1179{
1180        uint32_t rc = 0;
1181        if (TCG_IsShutdownPreBootInterface() == 0) {
1182                rc = TCG_PC_UNSUPPORTED;
1183        } else {
1184                rc = (TCG_PC_TPMERROR |
1185                      ((uint32_t)TCG_INTERFACE_SHUTDOWN << 16));
1186        }
1187
1188        if (rc != 0) {
1189                to->opblength = 4;
1190                to->reserved  = 0;
1191        }
1192
1193        return rc;
1194}
1195
1196static
1197uint32_t CompactHashLogExtendEvent32(unsigned char *buffer,
1198                                     uint32_t info,
1199                                     uint32_t magic,
1200                                     uint32_t length,
1201                                     uint32_t pcrindex,
1202                                     uint32_t *edx_ptr)
1203{
1204        uint32_t rc = 0;
1205        struct hleeo hleeo;
1206
1207        if (TCG_IsShutdownPreBootInterface() != 0) {
1208                rc = (TCG_PC_TPMERROR |
1209                      ((uint32_t)TCG_INTERFACE_SHUTDOWN << 16));
1210        }
1211
1212        if (buffer == 0) {
1213                rc = (TCG_PC_TPMERROR |
1214                      ((uint32_t)TCG_INVALID_INPUT_PARA << 16));
1215        }
1216
1217        if (rc == 0) {
1218                struct hleei_short hleei;
1219                struct pcpes pcpes;
1220                uint8_t *logdataptr;
1221                uint8_t *hashdataptr;
1222
1223                logdataptr = (uint8_t*)&pcpes;
1224                hashdataptr = buffer;
1225
1226                hleei.ipblength = 0x18;
1227                hleei.reserved  = 0x0;
1228                hleei.hashdataptr = (uint32_t)hashdataptr;
1229                hleei.hashdatalen = length;
1230                hleei.pcrindex = pcrindex;
1231                hleei.logdataptr = (uint32_t)logdataptr;
1232                hleei.logdatalen = 32;
1233
1234                memset(&pcpes, 0x0, 32);
1235                pcpes.pcrindex = pcrindex;
1236                pcpes.eventtype = 12; /* EV_COMPACT_HASH */
1237                pcpes.eventdatasize = 4;
1238                pcpes.event = info;
1239
1240                rc = HashLogExtendEvent32(&hleei,
1241                                          &hleeo,
1242                                          TCG_MAGIC,
1243                                          0x0,
1244                                          0x0);
1245        }
1246
1247        if (rc == 0) {
1248                *edx_ptr = hleeo.eventnumber;
1249        }
1250
1251        return rc;
1252}
1253
1254
1255
1256/*******************************************************************
1257  Calculation of SHA1 in SW
1258
1259  See: RFC3174, Wikipedia's SHA1 alogrithm description
1260 ******************************************************************/
1261typedef struct _sha1_ctx {
1262        uint32_t h[5];
1263} sha1_ctx;
1264
1265
1266static inline uint32_t rol(uint32_t val, uint16_t rol)
1267{
1268        return (val << rol) | (val >> (32 - rol));
1269}
1270
1271static const uint32_t sha_ko[4] = { 0x5a827999,
1272                                    0x6ed9eba1,
1273                                    0x8f1bbcdc,
1274                                    0xca62c1d6 };
1275
1276
1277static void sha1_block(uint32_t *w, sha1_ctx *ctx)
1278{
1279        uint32_t i;
1280        uint32_t a,b,c,d,e,f;
1281        uint32_t tmp;
1282        uint32_t idx;
1283
1284        /* change endianess of given data */
1285        for (i = 0; i < 16; i++) {
1286                w[i] = bswap(w[i]);
1287        }
1288
1289        for (i = 16; i <= 79; i++) {
1290                tmp = w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16];
1291                w[i] = rol(tmp,1);
1292        }
1293
1294        a = ctx->h[0];
1295        b = ctx->h[1];
1296        c = ctx->h[2];
1297        d = ctx->h[3];
1298        e = ctx->h[4];
1299
1300        for (i = 0; i <= 79; i++) {
1301                if (i <= 19) {
1302                        f = (b & c) | ((b ^ 0xffffffff) & d);
1303                        idx = 0;
1304                } else if (i <= 39) {
1305                        f = b ^ c ^ d;
1306                        idx = 1;
1307                } else if (i <= 59) {
1308                        f = (b & c) | (b & d) | (c & d);
1309                        idx = 2;
1310                } else {
1311                        f = b ^ c ^ d;
1312                        idx = 3;
1313                }
1314
1315                tmp = rol(a, 5) +
1316                      f +
1317                      e +
1318                      sha_ko[idx] +
1319                      w[i];
1320                e = d;
1321                d = c;
1322                c = rol(b, 30);
1323                b = a;
1324                a = tmp;
1325        }
1326
1327        ctx->h[0] += a;
1328        ctx->h[1] += b;
1329        ctx->h[2] += c;
1330        ctx->h[3] += d;
1331        ctx->h[4] += e;
1332}
1333
1334static
1335void sha1_do(sha1_ctx *ctx, const unsigned char *data32, uint32_t length)
1336{
1337        uint32_t offset;
1338        uint16_t num;
1339        uint32_t bits = 0;
1340        uint32_t w[80];
1341        uint32_t tmp;
1342
1343        /* treat data in 64-byte chunks */
1344        for (offset = 0; length - offset >= 64; offset += 64) {
1345                memcpy(w, data32 + offset, 64);
1346                sha1_block((uint32_t *)w, ctx);
1347                bits += (64 * 8);
1348        }
1349
1350        /* last block with less than 64 bytes */
1351        num = length - offset;
1352        bits += (num << 3);
1353
1354        memset(w, 0x0, 64);
1355        memcpy(w, data32 + offset, num);
1356        ((uint8_t *)w)[num] = 0x80;
1357
1358        if (num >= 56) {
1359                /* cannot append number of bits here */
1360                sha1_block((uint32_t *)w, ctx);
1361                memset(w, 0x0, 60);
1362        }
1363
1364        /* write number of bits to end of block */
1365        tmp = bswap(bits);
1366        memcpy(&w[15], &tmp, 4);
1367
1368        sha1_block(w, ctx);
1369
1370        /* need to switch result's endianess */
1371        for (num = 0; num < 5; num++)
1372                ctx->h[num] = bswap(ctx->h[num]);
1373}
1374
1375/* sha1 initialization constants */
1376static const uint32_t sha_const[5] = {
1377        0x67452301,
1378        0xefcdab89,
1379        0x98badcfe,
1380        0x10325476,
1381        0xc3d2e1f0
1382};
1383
1384static
1385void sha1(const unsigned char *data, uint32_t length, unsigned char *hash)
1386{
1387        sha1_ctx ctx;
1388
1389        memcpy(&ctx.h[0], sha_const, 20);
1390        sha1_do(&ctx, data, length);
1391        memcpy(hash, &ctx.h[0], 20);
1392}
1393
1394
1395uint32_t TCGInterruptHandler(pushad_regs_t *regs, uint32_t esds,
1396                             uint32_t flags_ptr)
1397{
1398        uint16_t DS = esds >> 16;
1399        uint16_t ES = esds & 0xffff;
1400        uint16_t *FLAGS = (uint16_t *)flags_ptr;
1401
1402        switch(regs->u.r8.al) {
1403        case 0x00:
1404                if (MA_IsTPMPresent() == 0) {
1405                        /* no TPM available */
1406                        regs->u.r32.eax = TCG_PC_TPMERROR |
1407                             ((uint32_t)(TCG_PC_TPM_NOT_PRESENT) << 16);
1408                } else {
1409                        regs->u.r32.eax = MA_InitTPM(TPM_ST_CLEAR);
1410                        if (regs->u.r32.eax == 0) {
1411                                regs->u.r32.ebx = TCG_MAGIC;
1412                                regs->u.r8.ch = TCG_VERSION_MAJOR;
1413                                regs->u.r8.cl = TCG_VERSION_MINOR;
1414                                regs->u.r32.edx = 0x0;
1415                                regs->u.r32.esi =
1416                                             (Bit32u)tcpa_get_lasa_base_ptr();
1417                                regs->u.r32.edi =
1418                                             (Bit32u)tcpa_get_lasa_last_ptr();
1419                                CLEAR_CF();
1420                        }
1421                }
1422                break;
1423        case 0x01:
1424                regs->u.r32.eax =
1425                        HashLogExtendEvent32((struct hleei_short*)
1426                                                ADDR_FROM_SEG_OFF(ES,
1427                                                      regs->u.r16.di),
1428                                            (struct hleeo*)
1429                                                ADDR_FROM_SEG_OFF(DS,
1430                                                      regs->u.r16.si),
1431                                            regs->u.r32.ebx,
1432                                            regs->u.r32.ecx,
1433                                            regs->u.r32.edx);
1434                CLEAR_CF();
1435                break;
1436        case 0x02:
1437                regs->u.r32.eax =
1438                        PassThroughToTPM32((struct pttti *)
1439                                                ADDR_FROM_SEG_OFF(ES,
1440                                                      regs->u.r16.di),
1441                                           (struct pttto *)
1442                                                ADDR_FROM_SEG_OFF(DS,
1443                                                      regs->u.r16.si),
1444                                           regs->u.r32.ebx,
1445                                           regs->u.r32.ecx,
1446                                           regs->u.r32.edx);
1447                CLEAR_CF();
1448                break;
1449        case 0x03:
1450                regs->u.r32.eax =
1451                        TCG_ShutdownPreBootInterface(regs->u.r32.ebx);
1452                CLEAR_CF();
1453                break;
1454        case 0x04:
1455                regs->u.r32.eax =
1456                        HashLogEvent32((struct hlei*)
1457                                                ADDR_FROM_SEG_OFF(ES,
1458                                                      regs->u.r16.di),
1459                                       (struct hleo*)
1460                                                ADDR_FROM_SEG_OFF(DS,
1461                                                      regs->u.r16.si),
1462                                           regs->u.r32.ebx,
1463                                           regs->u.r32.ecx,
1464                                           regs->u.r32.edx);
1465                CLEAR_CF();
1466                break;
1467        case 0x05:
1468                regs->u.r32.eax =
1469                        HashAll32((struct hai*)
1470                                        ADDR_FROM_SEG_OFF(ES,
1471                                                          regs->u.r16.di),
1472                                 (unsigned char *)
1473                                        ADDR_FROM_SEG_OFF(DS,
1474                                                          regs->u.r16.si),
1475                                   regs->u.r32.ebx,
1476                                   regs->u.r32.ecx,
1477                                   regs->u.r32.edx);
1478                CLEAR_CF();
1479                break;
1480        case 0x06:
1481                regs->u.r32.eax =
1482                        TSS32((struct ti*)ADDR_FROM_SEG_OFF(ES,
1483                                                            regs->u.r16.di),
1484                              (struct to*)ADDR_FROM_SEG_OFF(DS,
1485                                                            regs->u.r16.si),
1486                              regs->u.r32.ebx,
1487                              regs->u.r32.ecx,
1488                              regs->u.r32.edx);
1489                CLEAR_CF();
1490                break;
1491        case 0x07:
1492                regs->u.r32.eax =
1493                  CompactHashLogExtendEvent32((unsigned char *)
1494                                                  ADDR_FROM_SEG_OFF(ES,
1495                                                        regs->u.r16.di),
1496                                              regs->u.r32.esi,
1497                                              regs->u.r32.ebx,
1498                                              regs->u.r32.ecx,
1499                                              regs->u.r32.edx,
1500                                              &regs->u.r32.edx);
1501                CLEAR_CF();
1502                break;
1503        default:
1504                SET_CF();
1505        }
1506
1507        return 0;
1508}
Note: See TracBrowser for help on using the repository browser.