├── LICENSE ├── Makefile ├── README.md ├── base32.c ├── base32.h ├── dracut └── module-setup.sh ├── libtpm ├── Makefile ├── auditing.c ├── bind.c ├── chgauth.c ├── context.c ├── counter.c ├── daa.c ├── debug.c ├── delegation.c ├── dir.c ├── eviction.c ├── hmac.c ├── hmac.h ├── identity.c ├── keys.c ├── keyswap.c ├── maintenance.c ├── management.c ├── migrate.c ├── miscfunc.c ├── newserialize.h ├── nv.c ├── oiaposap.c ├── oiaposap.h ├── optin.c ├── owner.c ├── ownertpmdiag.c ├── pcrs.c ├── pcrs.h ├── raw.c ├── rng.c ├── seal.c ├── serialize.c ├── session.c ├── sha.c ├── signature.c ├── startup.c ├── testing.c ├── ticks.c ├── tpm.h ├── tpm_constants.h ├── tpm_error.h ├── tpm_lowlevel.h ├── tpm_structures.h ├── tpm_types.h ├── tpmfunc.h ├── tpmkeys.h ├── tpmutil.c ├── tpmutil.h ├── tpmutil_libtpms.c ├── tpmutil_sock.c ├── tpmutil_tty.c ├── tpmutil_unixio.c └── transport.c ├── plymouth-unsealtotp.c ├── sealtotp.c ├── tpmtotp.service └── unsealtotp.c /Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -ggdb -w -Ilibtpm -std=c99 -Wall -Wextra -Werror -DTPM_POSIX=1 -DTPM_NV_DISK=1 -DTPM_AES=1 -DTPM_V12=1 -DTPM_USE_TAG_IN_STRUCTURE=1 -DTPM_USE_CHARDEV=1 2 | 3 | 4 | PLYMOUTH_CFLAGS = `pkg-config --cflags ply-boot-client` 5 | 6 | LDLIBS=-Llibtpm -ltpm -lcrypto -loath 7 | 8 | PLYMOUTH_LDLIBS = `pkg-config --libs ply-boot-client` 9 | 10 | APPS=sealtotp unsealtotp plymouth-unsealtotp 11 | 12 | all: libtpm/libtpm.a $(APPS) 13 | 14 | libtpm/libtpm.a: 15 | $(MAKE) -C libtpm 16 | 17 | unsealtotp: unsealtotp.o 18 | 19 | plymouth-unsealtotp: plymouth-unsealtotp.c 20 | $(CC) $(CFLAGS) $(PLYMOUTH_CFLAGS) -o $@ $< $(PLYMOUTH_LDLIBS) $(LDLIBS) 21 | 22 | sealtotp: sealtotp.c base32.c 23 | $(CC) $(CFLAGS) -ltspi -lqrencode -o $@ $^ $(LDLIBS) 24 | 25 | clean: 26 | rm -f *.o $(APPS) 27 | $(MAKE) -C libtpm clean 28 | 29 | install: 30 | install sealtotp unsealtotp plymouth-unsealtotp /usr/bin/ 31 | install -D dracut/module-setup.sh /usr/lib/dracut/modules.d/60tpmtotp/module-setup.sh 32 | install -m 0644 tpmtotp.service /lib/systemd/system 33 | systemctl enable tpmtotp.service 34 | 35 | uninstall: 36 | rm /usr/bin/sealtotp /usr/bin/unsealtotp /usr/bin/plymouth-unsealtotp 37 | rm -rf /usr/lib/dracut/modules.d/60tpmtotp/ 38 | rm /lib/systemd/system/tpmtotp.service 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tpmtotp - attest computer boot state to phone via TOTP 2 | 3 | This is a small collection of tools for allowing "remote attestation" between 4 | a computer and a phone via TOTP. 5 | 6 | ## sealtotp 7 | 8 | Generates a TOTP token, seals it against the TPM using the state of PCRs 0-5 9 | and 7, saves it to the file given as the first argument and prints an ANSI QR 10 | code 11 | 12 | ## unsealtotp 13 | 14 | Takes the file given as the first argument, unseals it with the TPM and 15 | prints a TOTP value. 16 | 17 | ## usage 18 | 19 | sealtotp and unsealtotp both use libtpm to talk to the TPM directly, and so 20 | will not run if a TPM service daemon such as Trousers is running. In 21 | addition, they need access to /dev/tpm0 and so will normally need to be run 22 | as root. To use, do the following: 23 | 24 | ./sealtotp totpblob 25 | 26 | and enrol the QR code in an app like Google Authenticator. Copy totpblob and 27 | unsealtotp (and its dependencies) into your initrd and run 28 | 29 | ./unsealtotp totpblob 30 | 31 | or 32 | 33 | ./plymouth-unsealtotp totpblob 34 | 35 | in your boot process before requesting the disk decryption 36 | passphrase. Verify that the value matches the value on your phone before 37 | typing any passphrase. The plymouth variant talks to the Plymouth boot 38 | splash service and will display your token in the top left of the screen, 39 | updating every 30 seconds. 40 | 41 | ## TPM non-volatile storage 42 | 43 | If you pass the -n argument to sealtotp, the sealed secret will be stored 44 | in nvram on the TPM. plymouth-unsealtotp and unsealtotp will automatically 45 | attempt to obtain a secret from there before falling back to attempting to 46 | read from files. 47 | 48 | ## UEFI non-volatile storage 49 | 50 | If you use /sys/firmware/efi/efivars/ as a prefix to the filename, tpmtotp 51 | will handle inserting and removing appropriate attributes and so permit the 52 | storage of the encrypted secret as a UEFI variable. 53 | 54 | ## Using multiple filenames 55 | 56 | If you pass multiple filenames to the unseal commands, they will attempt to 57 | open each in turn and use the first that can be successfully opened. This 58 | allows you to attempt to open a UEFI variable and then fall back to an 59 | on-disk location. 60 | 61 | ## Passing PCR values 62 | 63 | You can choose which PCR values the secret is sealed to using the -p argument 64 | to sealtotp. A comma separated list of PCRs will default to using the current 65 | value of the PCR. If you are sealing a secret to calculated variables, you 66 | may pass them like so: 67 | 68 | ``` 69 | sealtotp -p 0=62 64 98 1C B8 2B D1 2F 45 C3 C2 06 18 6B C7 6E 23 EB 21 88, 1=3A 3F 78 0F 11 A4 B4 99 69 FC AA 80 CD 6E 39 57 C3 3B 22 75, 2=3A 3F 78 0F 11 A4 B4 99 69 FC AA 80 CD 6E 39 57 C3 3B 22 75 70 | ``` 71 | 72 | ## requirements 73 | 74 | sealtotp requires libqrencode. unsealtotp requires liboath. 75 | 76 | ## limitations 77 | 78 | The TPM policy measurement does not currently include the initrd or kernel 79 | that you are booting, since grub lacks support for performing the initial 80 | measurement of these objects. This results in the following vulnerability: 81 | 82 | 1) Shim will be measured into PCR[4] 83 | 84 | 2) Shim will verify that the next stage loader is signed with a trusted key 85 | 86 | 3) The next stage loader will verify that the kernel is signed with a 87 | trusted key 88 | 89 | 4) The initrd will be loaded without any verification, and so will be able 90 | to unseal the TOTP value while still providing a malicious codebase 91 | 92 | Avoiding this requires either signature validation of the initrd 93 | (problematic, as these are typically generated on the local system) or for 94 | the second stage loader (typically grub) to gain support for measuring its 95 | payloads into the TPM. 96 | 97 | An attacker who is able to perform DMA-based attacks may be able to boot the 98 | system, attach a DMA-capable device and extract the valid TOTP secret from 99 | RAM. This will allow them to spoof legitimate boots later on. This can be 100 | avoided by ensuring that your kernel and hardware support and enable an 101 | IOMMU, or by adding support to the kernel to allow enumeration of 102 | DMA-capable external devices to be deferred until later. 103 | 104 | Sufficiently malicious firmware may still be able to extract the TOTP secret 105 | from system RAM and exfiltrate it such that an attacker can later spoof 106 | legitimate boots on a compromised system. Of course, any such sufficiently 107 | malicious firmware is also capable of modifying your OS at runtime, so 108 | you've already lost. 109 | 110 | ## TODO 111 | 112 | Add commandline-switch to sealtotp for choosing trousers (tspi) vs direkt 113 | access (libtpm) 114 | 115 | Add support for migration of sealed data to new PCR values in order to 116 | support bootloader updates. 117 | 118 | Add TPM support to grub. 119 | 120 | Get distributions to turn on iommus. 121 | 122 | Modify the kernel to allow delayed enumeration of DMA-capable external 123 | devices. 124 | -------------------------------------------------------------------------------- /base32.c: -------------------------------------------------------------------------------- 1 | /** 2 | * base32 (de)coder implementation as specified by RFC4648. 3 | * 4 | * Copyright (c) 2010 Adrien Kunysz 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | **/ 24 | 25 | #include // assert() 26 | #include // CHAR_BIT 27 | 28 | #include "base32.h" 29 | 30 | /** 31 | * Let this be a sequence of plain data before encoding: 32 | * 33 | * 01234567 01234567 01234567 01234567 01234567 34 | * +--------+--------+--------+--------+--------+ 35 | * |< 0 >< 1| >< 2 ><|.3 >< 4.|>< 5 ><.|6 >< 7 >| 36 | * +--------+--------+--------+--------+--------+ 37 | * 38 | * There are 5 octets of 8 bits each in each sequence. 39 | * There are 8 blocks of 5 bits each in each sequence. 40 | * 41 | * You probably want to refer to that graph when reading the algorithms in this 42 | * file. We use "octet" instead of "byte" intentionnaly as we really work with 43 | * 8 bits quantities. This implementation will probably not work properly on 44 | * systems that don't have exactly 8 bits per (unsigned) char. 45 | **/ 46 | 47 | static size_t min(size_t x, size_t y) 48 | { 49 | return x < y ? x : y; 50 | } 51 | 52 | static const unsigned char PADDING_CHAR = '='; 53 | 54 | /** 55 | * Pad the given buffer with len padding characters. 56 | */ 57 | static void pad(unsigned char *buf, int len) 58 | { 59 | for (int i = 0; i < len; i++) 60 | buf[i] = PADDING_CHAR; 61 | } 62 | 63 | /** 64 | * This convert a 5 bits value into a base32 character. 65 | * Only the 5 least significant bits are used. 66 | */ 67 | static unsigned char encode_char(unsigned char c) 68 | { 69 | static unsigned char base32[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; 70 | return base32[c & 0x1F]; // 0001 1111 71 | } 72 | 73 | /** 74 | * Decode given character into a 5 bits value. 75 | * Returns -1 iff the argument given was an invalid base32 character 76 | * or a padding character. 77 | */ 78 | static int decode_char(unsigned char c) 79 | { 80 | char retval = -1; 81 | 82 | if (c >= 'A' && c <= 'Z') 83 | retval = c - 'A'; 84 | if (c >= '2' && c <= '7') 85 | retval = c - '2' + 26; 86 | 87 | assert(retval == -1 || ((retval & 0x1F) == retval)); 88 | 89 | return retval; 90 | } 91 | 92 | /** 93 | * Given a block id between 0 and 7 inclusive, this will return the index of 94 | * the octet in which this block starts. For example, given 3 it will return 1 95 | * because block 3 starts in octet 1: 96 | * 97 | * +--------+--------+ 98 | * | ......<|.3 >....| 99 | * +--------+--------+ 100 | * octet 1 | octet 2 101 | */ 102 | static int get_octet(int block) 103 | { 104 | assert(block >= 0 && block < 8); 105 | return (block*5) / 8; 106 | } 107 | 108 | /** 109 | * Given a block id between 0 and 7 inclusive, this will return how many bits 110 | * we can drop at the end of the octet in which this block starts. 111 | * For example, given block 0 it will return 3 because there are 3 bits 112 | * we don't care about at the end: 113 | * 114 | * +--------+- 115 | * |< 0 >...| 116 | * +--------+- 117 | * 118 | * Given block 1, it will return -2 because there 119 | * are actually two bits missing to have a complete block: 120 | * 121 | * +--------+- 122 | * |.....< 1|.. 123 | * +--------+- 124 | **/ 125 | static int get_offset(int block) 126 | { 127 | assert(block >= 0 && block < 8); 128 | return (8 - 5 - (5*block) % 8); 129 | } 130 | 131 | /** 132 | * Like "b >> offset" but it will do the right thing with negative offset. 133 | * We need this as bitwise shifting by a negative offset is undefined 134 | * behavior. 135 | */ 136 | static unsigned char shift_right(unsigned char byte, signed char offset) 137 | { 138 | if (offset > 0) 139 | return byte >> offset; 140 | else 141 | return byte << -offset; 142 | } 143 | 144 | static unsigned char shift_left(unsigned char byte, signed char offset) 145 | { 146 | return shift_right(byte, - offset); 147 | } 148 | 149 | /** 150 | * Encode a sequence. A sequence is no longer than 5 octets by definition. 151 | * Thus passing a length greater than 5 to this function is an error. Encoding 152 | * sequences shorter than 5 octets is supported and padding will be added to the 153 | * output as per the specification. 154 | */ 155 | static void encode_sequence(const unsigned char *plain, int len, unsigned char *coded) 156 | { 157 | assert(CHAR_BIT == 8); // not sure this would work otherwise 158 | assert(len >= 0 && len <= 5); 159 | 160 | for (int block = 0; block < 8; block++) { 161 | int octet = get_octet(block); // figure out which octet this block starts in 162 | int junk = get_offset(block); // how many bits do we drop from this octet? 163 | 164 | if (octet >= len) { // we hit the end of the buffer 165 | pad(&coded[block], 8 - block); 166 | return; 167 | } 168 | 169 | unsigned char c = shift_right(plain[octet], junk); // first part 170 | 171 | if (junk < 0 // is there a second part? 172 | && octet < len - 1) // is there still something to read? 173 | { 174 | c |= shift_right(plain[octet+1], 8 + junk); 175 | } 176 | coded[block] = encode_char(c); 177 | } 178 | } 179 | 180 | void base32_encode(const unsigned char *plain, size_t len, unsigned char *coded) 181 | { 182 | // All the hard work is done in encode_sequence(), 183 | // here we just need to feed it the data sequence by sequence. 184 | for (size_t i = 0, j = 0; i < len; i += 5, j += 8) { 185 | encode_sequence(&plain[i], min(len - i, 5), &coded[j]); 186 | } 187 | } 188 | 189 | static int decode_sequence(const unsigned char *coded, unsigned char *plain) 190 | { 191 | assert(CHAR_BIT == 8); 192 | assert(coded && plain); 193 | 194 | plain[0] = 0; 195 | for (int block = 0; block < 8; block++) { 196 | int offset = get_offset(block); 197 | int octet = get_octet(block); 198 | 199 | int c = decode_char(coded[block]); 200 | if (c < 0) // invalid char, stop here 201 | return octet; 202 | 203 | plain[octet] |= shift_left(c, offset); 204 | if (offset < 0) { // does this block overflows to next octet? 205 | assert(octet < 4); 206 | plain[octet+1] = shift_left(c, 8 + offset); 207 | } 208 | } 209 | return 5; 210 | } 211 | 212 | size_t base32_decode(const unsigned char *coded, unsigned char *plain) 213 | { 214 | size_t written = 0; 215 | for (size_t i = 0, j = 0; ; i += 8, j += 5) { 216 | int n = decode_sequence(&coded[i], &plain[j]); 217 | written += n; 218 | if (n < 5) 219 | return written; 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /base32.h: -------------------------------------------------------------------------------- 1 | /** 2 | * base32 (de)coder implementation as specified by RFC4648. 3 | * 4 | * Copyright (c) 2010 Adrien Kunysz 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | **/ 24 | 25 | #ifndef __BASE32_H_ 26 | #define __BASE32_H_ 27 | 28 | #include // size_t 29 | 30 | /** 31 | * Returns the length of the output buffer required to encode len bytes of 32 | * data into base32. This is a macro to allow users to define buffer size at 33 | * compilation time. 34 | */ 35 | #define BASE32_LEN(len) (((len)/5)*8 + ((len) % 5 ? 8 : 0)) 36 | 37 | /** 38 | * Returns the length of the output buffer required to decode a base32 string 39 | * of len characters. Please note that len must be a multiple of 8 as per 40 | * definition of a base32 string. This is a macro to allow users to define 41 | * buffer size at compilation time. 42 | */ 43 | #define UNBASE32_LEN(len) (((len)/8)*5) 44 | 45 | /** 46 | * Encode the data pointed to by plain into base32 and store the 47 | * result at the address pointed to by coded. The "coded" argument 48 | * must point to a location that has enough available space 49 | * to store the whole coded string. The resulting string will only 50 | * contain characters from the [A-Z2-7=] set. The "len" arguments 51 | * define how many bytes will be read from the "plain" buffer. 52 | **/ 53 | void base32_encode(const unsigned char *plain, size_t len, unsigned char *coded); 54 | 55 | /** 56 | * Decode the null terminated string pointed to by coded and write 57 | * the decoded data into the location pointed to by plain. The 58 | * "plain" argument must point to a location that has enough available 59 | * space to store the whole decoded string. 60 | * Returns the length of the decoded string. This may be less than 61 | * expected due to padding. If an invalid base32 character is found 62 | * in the coded string, decoding will stop at that point. 63 | **/ 64 | size_t base32_decode(const unsigned char *coded, unsigned char *plain); 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /dracut/module-setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | check() { 4 | require_binaries unsealtotp 5 | if [ ! -f /etc/tpmtotp ] && [ ! -f /sys/firmware/efi/efivars/TPMTOTP-6d6a372e-bd74-4ede-975d-df44eccf8226 ]; then 6 | return 1; 7 | fi 8 | } 9 | 10 | depends() { 11 | echo plymouth 12 | } 13 | 14 | install() { 15 | inst_simple /usr/bin/plymouth-unsealtotp 16 | if [ -f /etc/tpmtotp ]; then 17 | inst_simple /etc/tpmtotp 18 | fi 19 | inst_simple "/etc/adjtime" 20 | inst_simple "/etc/localtime" 21 | inst_simple "${systemdsystemunitdir}/tpmtotp.service" 22 | inst_libdir_file "plymouth/label.so" 23 | inst_simple "/usr/share/fonts/dejavu/DejaVuSans.ttf" 24 | instmods tpm_tis 25 | mkdir -p "${initdir}${systemdsystemconfdir}/sysinit.target.wants" 26 | ln_r "${systemdsystemunitdir}/tpmtotp.service" "${systemdsystemconfdir}/sysinit.target.wants/" 27 | } 28 | -------------------------------------------------------------------------------- /libtpm/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -ggdb -Wall -w -I. -DTPM_POSIX=1 -DTPM_NV_DISK=1 -DTPM_AES=1 -DTPM_V12=1 -DTPM_USE_TAG_IN_STRUCTURE=1 -DTPM_USE_CHARDEV=1 2 | 3 | LIBRARIES = libtpm.a 4 | HEADERS = tpmfunc.h tpm.h tpmkeys.h 5 | SOURCES = auditing.c bind.c chgauth.c context.c \ 6 | counter.c daa.c debug.c delegation.c dir.c \ 7 | eviction.c hmac.c identity.c keys.c keyswap.c \ 8 | maintenance.c management.c migrate.c miscfunc.c nv.c \ 9 | oiaposap.c optin.c owner.c ownertpmdiag.c \ 10 | pcrs.c raw.c rng.c seal.c serialize.c session.c \ 11 | sha.c signature.c startup.c testing.c \ 12 | ticks.c tpmutil.c tpmutil_sock.c tpmutil_tty.c tpmutil_unixio.c \ 13 | tpmutil_libtpms.c \ 14 | transport.c 15 | OBJECTS = auditing.o bind.o chgauth.o context.o \ 16 | counter.o daa.o debug.o delegation.o dir.o \ 17 | eviction.o hmac.o identity.o keys.o keyswap.o \ 18 | maintenance.o management.o migrate.o miscfunc.o nv.o \ 19 | oiaposap.o optin.o owner.o ownertpmdiag.o \ 20 | pcrs.o raw.o rng.o seal.o serialize.o session.o \ 21 | sha.o signature.o startup.o testing.o \ 22 | ticks.o tpmutil.o tpmutil_sock.o tpmutil_tty.o tpmutil_unixio.o \ 23 | tpmutil_libtpms.o \ 24 | transport.o 25 | EXTRA_DIST = hmac.h oiaposap.h pcrs.h tpmutil.h 26 | 27 | libtpm.a: $(OBJECTS) 28 | ar -rcs libtpm.a $(OBJECTS) 29 | 30 | clean: 31 | rm -f *.o libtpm.a 32 | -------------------------------------------------------------------------------- /libtpm/bind.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Bind/Unbind routines */ 4 | /* Written by J. Kravitz */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: bind.c 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #include 41 | #include 42 | #include 43 | #ifdef TPM_POSIX 44 | #include 45 | #endif 46 | #ifdef TPM_WINDOWS 47 | #include 48 | #endif 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | 58 | 59 | /****************************************************************************/ 60 | /* */ 61 | /* Unbind a data object */ 62 | /* */ 63 | /* The arguments are... */ 64 | /* */ 65 | /* keyhandle is the handle of the key used to bind the data */ 66 | /* 0x40000000 for the SRK */ 67 | /* keyauth is the authorization data (password) for the key */ 68 | /* if NULL, it is assumed that the key needs no authorization */ 69 | /* data is a pointer to the data to be unbound */ 70 | /* datalen is the length of the data to be unbound (max 256?) */ 71 | /* blob is a pointer to an area to received the unbound data */ 72 | /* bloblen is a pointer to an integer which will receive the length */ 73 | /* of the unbound data */ 74 | /* */ 75 | /****************************************************************************/ 76 | uint32_t TPM_UnBind(uint32_t keyhandle, 77 | unsigned char *keyauth, 78 | unsigned char *data, uint32_t datalen, 79 | unsigned char *blob, uint32_t *bloblen) 80 | { 81 | uint32_t ret = 0; 82 | STACK_TPM_BUFFER(tpmdata) 83 | session sess; 84 | unsigned char pubauth[TPM_HASH_SIZE]; 85 | unsigned char nonceodd[TPM_NONCE_SIZE]; 86 | unsigned char c = 0; 87 | uint32_t ordinal = htonl(TPM_ORD_UnBind); 88 | uint32_t datsize = htonl(datalen); 89 | uint32_t keyhndl = htonl(keyhandle); 90 | uint16_t keytype; 91 | uint32_t infosize; 92 | 93 | /* check input arguments */ 94 | if (data == NULL || blob == NULL) return ERR_NULL_ARG; 95 | if (keyhandle == 0x40000000) keytype = TPM_ET_SRK; 96 | else keytype = TPM_ET_KEYHANDLE; 97 | 98 | ret = needKeysRoom(keyhandle, 0 , 0, 0); 99 | if (ret != 0) { 100 | return ret; 101 | } 102 | 103 | if (keyauth != NULL) /* key needs authorization */ { 104 | /* Open OSAP Session */ 105 | ret = TSS_SessionOpen(SESSION_OSAP|SESSION_DSAP,&sess,keyauth,keytype,keyhandle); 106 | if (ret != 0) { 107 | return ret; 108 | } 109 | /* generate odd nonce */ 110 | TSS_gennonce(nonceodd); 111 | /* move Network byte order data to variables for HMAC calculation */ 112 | /* calculate authorization HMAC value */ 113 | ret = TSS_authhmac(pubauth,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE,TSS_Session_GetENonce(&sess),nonceodd,c, 114 | TPM_U32_SIZE,&ordinal, 115 | TPM_U32_SIZE,&datsize, 116 | datalen,data,0,0); 117 | if (ret != 0) { 118 | TSS_SessionClose(&sess); 119 | return ret; 120 | } 121 | /* build the request buffer */ 122 | ret = TSS_buildbuff("00 C2 T l l @ L % o %",&tpmdata, 123 | ordinal, 124 | keyhndl, 125 | datalen,data, 126 | TSS_Session_GetHandle(&sess), 127 | TPM_NONCE_SIZE,nonceodd, 128 | c, 129 | TPM_HASH_SIZE,pubauth); 130 | if ((ret & ERR_MASK) != 0) { 131 | TSS_SessionClose(&sess); 132 | return ret; 133 | } 134 | /* transmit the request buffer to the TPM device and read the reply */ 135 | ret = TPM_Transmit(&tpmdata,"UnBind"); 136 | TSS_SessionClose(&sess); 137 | 138 | if (ret != 0) { 139 | return ret; 140 | } 141 | /* calculate the size of the returned Blob */ 142 | ret = tpm_buffer_load32(&tpmdata,TPM_DATA_OFFSET, &infosize); 143 | if ((ret & ERR_MASK)) { 144 | return ret; 145 | } 146 | /* check the HMAC in the response */ 147 | ret = TSS_checkhmac1(&tpmdata,ordinal,nonceodd,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE, 148 | TPM_U32_SIZE,TPM_DATA_OFFSET, 149 | infosize,TPM_DATA_OFFSET + TPM_U32_SIZE, 150 | 0,0); 151 | if (ret != 0) { 152 | return ret; 153 | } 154 | /* copy the returned blob to caller */ 155 | memcpy(blob, 156 | &tpmdata.buffer[TPM_DATA_OFFSET+TPM_U32_SIZE], 157 | infosize); 158 | *bloblen = infosize; 159 | } else { /* key needs NO authorization */ 160 | /* move Network byte order data to variables for HMAC calculation */ 161 | 162 | /* build the request buffer */ 163 | ret = TSS_buildbuff("00 C1 T l l @",&tpmdata, 164 | ordinal, 165 | keyhndl, 166 | datalen,data); 167 | if ((ret & ERR_MASK) != 0) 168 | return ret; 169 | /* transmit the request buffer to the TPM device and read the reply */ 170 | ret = TPM_Transmit(&tpmdata,"UnBind"); 171 | if (ret != 0) 172 | return ret; 173 | /* calculate the size of the returned Blob */ 174 | ret = tpm_buffer_load32(&tpmdata,TPM_DATA_OFFSET,&infosize); 175 | if ((ret & ERR_MASK)) { 176 | return ret; 177 | } 178 | /* copy the returned blob to caller */ 179 | memcpy(blob, 180 | &tpmdata.buffer[TPM_DATA_OFFSET+TPM_U32_SIZE], 181 | infosize); 182 | *bloblen = infosize; 183 | } 184 | return ret; 185 | } 186 | 187 | /****************************************************************************/ 188 | /* */ 189 | /* bind a data object */ 190 | /* */ 191 | /* The arguments are... */ 192 | /* */ 193 | /* key is a pointer to a OpenSSL RSA public key */ 194 | /* data is a pointer to the data to be bound */ 195 | /* datalen is the length of the data to be bound (max 256) */ 196 | /* blob is a pointer to an area to receive the bound data */ 197 | /* bloblen is a pointer to an integer which will receive the length */ 198 | /* of the bound data */ 199 | /* */ 200 | /****************************************************************************/ 201 | uint32_t TSS_Bind(RSA *key, 202 | const struct tpm_buffer *data, 203 | struct tpm_buffer *blob) 204 | { 205 | uint32_t ret; 206 | unsigned char * blob2 = NULL; 207 | int size = RSA_size(key); 208 | unsigned char tcpa[] = "TCPA"; 209 | 210 | blob2 = malloc(size); 211 | if (NULL == blob2) { 212 | return ERR_MEM_ERR; 213 | } 214 | /* check input arguments */ 215 | if (key == NULL || data == NULL || blob == NULL) 216 | return ERR_NULL_ARG; 217 | 218 | ret = RSA_padding_add_PKCS1_OAEP(blob2,size,data->buffer,data->used,tcpa,4); 219 | if (ret != 1) { 220 | free(blob2); 221 | return ERR_CRYPT_ERR; 222 | } 223 | ret = RSA_public_encrypt(size,blob2,blob->buffer,key,RSA_NO_PADDING); 224 | free(blob2); 225 | if ((int)ret == -1) 226 | return ERR_CRYPT_ERR; 227 | blob->used = ret; 228 | return 0; 229 | } 230 | 231 | uint32_t TSS_BindPKCSv15(RSA *key, 232 | const struct tpm_buffer *data, 233 | struct tpm_buffer *blob) 234 | { 235 | uint32_t ret; 236 | unsigned char * blob2 = NULL; 237 | int size = RSA_size(key); 238 | 239 | blob2 = malloc(size); 240 | if (NULL == blob2) { 241 | return ERR_MEM_ERR; 242 | } 243 | /* check input arguments */ 244 | if (key == NULL || data == NULL || blob == NULL) 245 | return ERR_NULL_ARG; 246 | 247 | ret = RSA_padding_add_PKCS1_type_2(blob2,size,data->buffer,data->used); 248 | if (ret != 1) { 249 | free(blob2); 250 | return ERR_CRYPT_ERR; 251 | } 252 | ret = RSA_public_encrypt(size,blob2,blob->buffer,key,RSA_NO_PADDING); 253 | free(blob2); 254 | if ((int)ret == -1) { 255 | return ERR_CRYPT_ERR; 256 | } 257 | blob->used = ret; 258 | return 0; 259 | } 260 | -------------------------------------------------------------------------------- /libtpm/context.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Context Management Routines */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: context.c 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #include 41 | #include 42 | #include 43 | #ifdef TPM_POSIX 44 | #include 45 | #endif 46 | #ifdef TPM_WINDOWS 47 | #include 48 | #endif 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | uint32_t TPM_SaveKeyContext(uint32_t keyhandle, 58 | struct tpm_buffer *context) 59 | { 60 | uint32_t ret; 61 | uint32_t ordinal_no = htonl(TPM_ORD_SaveKeyContext); 62 | STACK_TPM_BUFFER(tpmdata) 63 | uint32_t keyhandle_no = htonl(keyhandle); 64 | uint32_t len; 65 | 66 | ret = needKeysRoom(keyhandle, 0, 0, 0); 67 | if (ret != 0) { 68 | return ret; 69 | } 70 | 71 | ret = TSS_buildbuff("00 c1 T l l",&tpmdata, 72 | ordinal_no, 73 | keyhandle_no); 74 | if (( ret & ERR_MASK )!= 0) { 75 | return ret; 76 | } 77 | 78 | ret = TPM_Transmit(&tpmdata,"SaveKeyContext"); 79 | 80 | if (ret != 0) { 81 | return ret; 82 | } 83 | 84 | ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET, &len); 85 | if ((ret & ERR_MASK)) { 86 | return ret; 87 | } 88 | 89 | if (NULL != context) { 90 | SET_TPM_BUFFER(context, 91 | &tpmdata.buffer[TPM_DATA_OFFSET+TPM_U32_SIZE], 92 | len); 93 | } 94 | 95 | return ret; 96 | } 97 | 98 | 99 | uint32_t TPM_LoadKeyContext(struct tpm_buffer *context, 100 | uint32_t *keyhandle) 101 | { 102 | uint32_t ret; 103 | uint32_t ordinal_no = htonl(TPM_ORD_LoadKeyContext); 104 | STACK_TPM_BUFFER(tpmdata); 105 | 106 | ret = TSS_buildbuff("00 c1 T l @",&tpmdata, 107 | ordinal_no, 108 | context->used, context->buffer); 109 | if ((ret & ERR_MASK) != 0) { 110 | return ret; 111 | } 112 | 113 | ret = TPM_Transmit(&tpmdata,"LoadKeyContext"); 114 | 115 | if (ret != 0) { 116 | return ret; 117 | } 118 | 119 | ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET, keyhandle); 120 | if ((ret & ERR_MASK)) { 121 | return ret; 122 | } 123 | 124 | return ret; 125 | } 126 | 127 | 128 | 129 | 130 | uint32_t TPM_SaveAuthContext(uint32_t authhandle, 131 | unsigned char * authContextBlob, uint32_t * authContextSize) 132 | { 133 | uint32_t ret; 134 | uint32_t ordinal_no = htonl(TPM_ORD_SaveAuthContext); 135 | STACK_TPM_BUFFER(tpmdata) 136 | uint32_t authhandle_no = htonl(authhandle); 137 | uint32_t len; 138 | 139 | ret = TSS_buildbuff("00 c1 T l l",&tpmdata, 140 | ordinal_no, 141 | authhandle_no); 142 | if (( ret & ERR_MASK )!= 0) { 143 | return ret; 144 | } 145 | 146 | ret = TPM_Transmit(&tpmdata,"SaveAuthContext"); 147 | 148 | if (ret != 0) { 149 | return ret; 150 | } 151 | 152 | ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET, &len); 153 | if ((ret & ERR_MASK)) { 154 | return ret; 155 | } 156 | 157 | if (NULL != authContextBlob) { 158 | *authContextSize = MIN(*authContextSize, len); 159 | memcpy(authContextBlob, 160 | &tpmdata.buffer[TPM_DATA_OFFSET+TPM_U32_SIZE], 161 | *authContextSize); 162 | } 163 | 164 | return ret; 165 | } 166 | 167 | 168 | uint32_t TPM_LoadAuthContext(unsigned char *authContextBlob, uint32_t authContextSize, 169 | uint32_t *authhandle) 170 | { 171 | uint32_t ret; 172 | uint32_t ordinal_no = htonl(TPM_ORD_LoadAuthContext); 173 | STACK_TPM_BUFFER(tpmdata); 174 | 175 | ret = TSS_buildbuff("00 c1 T l @",&tpmdata, 176 | ordinal_no, 177 | authContextSize, authContextBlob); 178 | if ( ( ret & ERR_MASK ) != 0) { 179 | return ret; 180 | } 181 | 182 | ret = TPM_Transmit(&tpmdata,"LoadAuthContext"); 183 | 184 | if (ret != 0) { 185 | return ret; 186 | } 187 | 188 | ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET, authhandle); 189 | if ((ret & ERR_MASK)) { 190 | return ret; 191 | } 192 | 193 | return ret; 194 | } 195 | -------------------------------------------------------------------------------- /libtpm/daa.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM DAA Routines */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: daa.c 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #include 41 | #include 42 | #include 43 | #ifdef TPM_POSIX 44 | #include 45 | #endif 46 | #ifdef TPM_WINDOWS 47 | #include 48 | #endif 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | uint32_t TPM_DAA_Join(uint32_t sesshandle, 58 | unsigned char * ownerauth, // HMAC key 59 | unsigned char stage, 60 | unsigned char * inputData0, uint32_t inputData0Size, 61 | unsigned char * inputData1, uint32_t inputData1Size, 62 | unsigned char * outputData, uint32_t * outputDataSize 63 | ) 64 | { 65 | STACK_TPM_BUFFER(tpmdata) 66 | unsigned char nonceodd[TPM_NONCE_SIZE]; 67 | unsigned char authdata[TPM_NONCE_SIZE]; 68 | unsigned char c = 0; 69 | uint32_t ordinal_no = htonl(TPM_ORD_DAA_Join); 70 | uint32_t sesshandle_no = htonl(sesshandle); 71 | uint32_t inputData0Size_no = htonl(inputData0Size); 72 | uint32_t inputData1Size_no = htonl(inputData1Size); 73 | uint32_t ret; 74 | uint32_t len; 75 | session sess; 76 | 77 | /* check input arguments */ 78 | if (NULL == inputData0) { 79 | inputData0Size = 0; 80 | } 81 | if (NULL == inputData1) { 82 | inputData1Size = 0; 83 | } 84 | 85 | /* generate odd nonce */ 86 | ret = TSS_gennonce(nonceodd); 87 | if (0 == ret) return ERR_CRYPT_ERR; 88 | /* Open OIAP Session */ 89 | ret = TSS_SessionOpen(SESSION_DSAP|SESSION_OSAP|SESSION_OIAP, 90 | &sess, 91 | ownerauth, TPM_ET_OWNER, 0); 92 | if (ret != 0) return ret; 93 | /* move Network byte order data to variable for HMAC calculation */ 94 | 95 | ret = TSS_authhmac(authdata,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE,TSS_Session_GetENonce(&sess),nonceodd,c, 96 | TPM_U32_SIZE, &ordinal_no, 97 | sizeof(BYTE), &stage, 98 | TPM_U32_SIZE, &inputData0Size_no, 99 | inputData0Size, inputData0, 100 | TPM_U32_SIZE, &inputData1Size_no, 101 | inputData1Size, inputData1, 102 | 0,0); 103 | if (0 != ret) { 104 | TSS_SessionClose(&sess); 105 | return ret; 106 | } 107 | 108 | /* build the request buffer */ 109 | ret = TSS_buildbuff("00 c2 T l l o @ @ L % o %", &tpmdata, 110 | ordinal_no, 111 | sesshandle_no, 112 | stage, 113 | inputData0Size, inputData0, 114 | inputData1Size, inputData1, 115 | TSS_Session_GetHandle(&sess), 116 | TPM_NONCE_SIZE,nonceodd, 117 | c, 118 | TPM_HASH_SIZE,authdata); 119 | 120 | if ( 0 != (ret & ERR_MASK)) { 121 | TSS_SessionClose(&sess); 122 | return ret; 123 | } 124 | 125 | ret = TPM_Transmit(&tpmdata,"TPM_DAA_Join - AUTH1"); 126 | TSS_SessionClose(&sess); 127 | 128 | if (0 != ret) { 129 | return ret; 130 | } 131 | 132 | ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET, &len); 133 | if ((ret & ERR_MASK)) { 134 | return ret; 135 | } 136 | 137 | ret = TSS_checkhmac1(&tpmdata,ordinal_no,nonceodd,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE, 138 | TPM_U32_SIZE + len, TPM_DATA_OFFSET, 139 | 0,0); 140 | 141 | if (0 != ret) { 142 | return ret; 143 | } 144 | 145 | if (NULL != outputData) { 146 | *outputDataSize = MIN(*outputDataSize, len); 147 | memcpy(outputData, 148 | &tpmdata.buffer[TPM_DATA_OFFSET+TPM_U32_SIZE] , 149 | *outputDataSize); 150 | } 151 | 152 | return ret; 153 | } 154 | 155 | 156 | 157 | uint32_t TPM_DAA_Sign(uint32_t sesshandle, 158 | unsigned char * ownerauth, // HMAC key 159 | unsigned char stage, 160 | unsigned char * inputData0, uint32_t inputData0Size, 161 | unsigned char * inputData1, uint32_t inputData1Size, 162 | unsigned char * outputData, uint32_t * outputDataSize 163 | ) 164 | { 165 | STACK_TPM_BUFFER(tpmdata) 166 | unsigned char nonceodd[TPM_NONCE_SIZE]; 167 | unsigned char authdata[TPM_NONCE_SIZE]; 168 | unsigned char c = 0; 169 | uint32_t ordinal_no = htonl(TPM_ORD_DAA_Sign); 170 | uint32_t sesshandle_no = htonl(sesshandle); 171 | uint32_t inputData0Size_no = htonl(inputData0Size); 172 | uint32_t inputData1Size_no = htonl(inputData1Size); 173 | uint32_t ret; 174 | uint32_t len; 175 | session sess; 176 | 177 | /* check input arguments */ 178 | if (NULL == inputData0) { 179 | inputData0Size = 0; 180 | } 181 | if (NULL == inputData1) { 182 | inputData1Size = 0; 183 | } 184 | 185 | /* generate odd nonce */ 186 | ret = TSS_gennonce(nonceodd); 187 | if (0 == ret) return ERR_CRYPT_ERR; 188 | /* Open OIAP Session */ 189 | ret = TSS_SessionOpen(SESSION_DSAP|SESSION_OSAP|SESSION_OIAP, 190 | &sess, 191 | ownerauth, TPM_ET_OWNER, 0); 192 | if (ret != 0) return ret; 193 | /* move Network byte order data to variable for HMAC calculation */ 194 | 195 | ret = TSS_authhmac(authdata,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE,TSS_Session_GetENonce(&sess),nonceodd,c, 196 | TPM_U32_SIZE, &ordinal_no, 197 | sizeof(BYTE), &stage, 198 | TPM_U32_SIZE, &inputData0Size_no, 199 | inputData0Size, inputData0, 200 | TPM_U32_SIZE, &inputData1Size_no, 201 | inputData1Size, inputData1, 202 | 0,0); 203 | if (0 != ret) { 204 | TSS_SessionClose(&sess); 205 | return ret; 206 | } 207 | 208 | /* build the request buffer */ 209 | ret = TSS_buildbuff("00 c2 T l l o @ @ L % o %", &tpmdata, 210 | ordinal_no, 211 | sesshandle_no, 212 | stage, 213 | inputData0Size, inputData0, 214 | inputData1Size, inputData1, 215 | TSS_Session_GetHandle(&sess), 216 | TPM_NONCE_SIZE,nonceodd, 217 | c, 218 | TPM_HASH_SIZE,authdata); 219 | 220 | if ( 0 != (ret & ERR_MASK)) { 221 | TSS_SessionClose(&sess); 222 | return ret; 223 | } 224 | 225 | ret = TPM_Transmit(&tpmdata,"TPM_DAA_Join"); 226 | 227 | TSS_SessionClose(&sess); 228 | if (0 != ret) { 229 | return ret; 230 | } 231 | 232 | ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET, &len); 233 | if ((ret & ERR_MASK)) { 234 | return ret; 235 | } 236 | 237 | ret = TSS_checkhmac1(&tpmdata,ordinal_no,nonceodd,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE, 238 | TPM_U32_SIZE + len, TPM_DATA_OFFSET, 239 | 0,0); 240 | 241 | if (0 != ret) { 242 | return ret; 243 | } 244 | 245 | if (NULL != outputData) { 246 | *outputDataSize = MIN(*outputDataSize, len); 247 | memcpy(outputData, 248 | &tpmdata.buffer[TPM_DATA_OFFSET+TPM_U32_SIZE], 249 | *outputDataSize); 250 | } 251 | 252 | return ret; 253 | } 254 | -------------------------------------------------------------------------------- /libtpm/debug.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Debug */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: debug.c 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | 41 | #include 42 | #include 43 | 44 | #include "tpmfunc.h" 45 | 46 | void print_array(const char *name, const unsigned char *data, unsigned int len) 47 | { 48 | unsigned int i = 0; 49 | printf("%s \n",name); 50 | while (i < len) { 51 | printf("0x%02X ",data[i]); 52 | i++; 53 | if (0 == (i & 0xf)) { 54 | printf("\n"); 55 | } 56 | } 57 | printf("\n"); 58 | } 59 | -------------------------------------------------------------------------------- /libtpm/dir.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Dir Routines */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: dir.c 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #include 41 | #include 42 | #include 43 | #ifdef TPM_POSIX 44 | #include 45 | #endif 46 | #ifdef TPM_WINDOWS 47 | #include 48 | #endif 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | uint32_t TPM_DirWriteAuth(uint32_t dirIndex, 58 | unsigned char * newValue, 59 | unsigned char * ownerAuth) 60 | { 61 | STACK_TPM_BUFFER(tpmdata) 62 | uint32_t ordinal_no = htonl(TPM_ORD_DirWriteAuth); 63 | uint32_t ret; 64 | uint32_t dirIndex_no = htonl(dirIndex); 65 | 66 | unsigned char nonceodd[TPM_NONCE_SIZE]; 67 | unsigned char authdata[TPM_NONCE_SIZE]; 68 | session sess; 69 | int c = 0; 70 | 71 | /* check input arguments */ 72 | if (NULL == ownerAuth || 73 | NULL == newValue) { 74 | return ERR_NULL_ARG; 75 | } 76 | 77 | 78 | /* Open OSAP Session */ 79 | ret = TSS_SessionOpen(SESSION_DSAP | SESSION_OSAP | SESSION_OIAP, 80 | &sess, 81 | ownerAuth, TPM_ET_OWNER, 0); 82 | 83 | if (ret != 0) 84 | return ret; 85 | 86 | /* generate odd nonce */ 87 | ret = TSS_gennonce(nonceodd); 88 | if (0 == ret) 89 | return ERR_CRYPT_ERR; 90 | 91 | /* move Network byte order data to variable for HMAC calculation */ 92 | ret = TSS_authhmac(authdata,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE,TSS_Session_GetENonce(&sess),nonceodd,c, 93 | TPM_U32_SIZE,&ordinal_no, 94 | TPM_U32_SIZE,&dirIndex_no, 95 | TPM_HASH_SIZE, newValue, 96 | 0,0); 97 | 98 | if (0 != ret) { 99 | TSS_SessionClose(&sess); 100 | return ret; 101 | } 102 | /* build the request buffer */ 103 | ret = TSS_buildbuff("00 c2 T l l % L % o %", &tpmdata, 104 | ordinal_no, 105 | dirIndex_no, 106 | TPM_HASH_SIZE, newValue, 107 | TSS_Session_GetHandle(&sess), 108 | TPM_HASH_SIZE, nonceodd, 109 | c, 110 | TPM_HASH_SIZE, authdata); 111 | 112 | 113 | if ((ret & ERR_MASK)) { 114 | TSS_SessionClose(&sess); 115 | return ret; 116 | } 117 | 118 | /* transmit the request buffer to the TPM device and read the reply */ 119 | ret = TPM_Transmit(&tpmdata,"DirWriteAuth"); 120 | TSS_SessionClose(&sess); 121 | 122 | if (ret != 0) { 123 | return ret; 124 | } 125 | /* check the HMAC in the response */ 126 | 127 | ret = TSS_checkhmac1(&tpmdata,ordinal_no,nonceodd,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE, 128 | 0,0); 129 | 130 | return ret; 131 | } 132 | 133 | 134 | uint32_t TPM_DirRead(uint32_t dirIndex, 135 | unsigned char * dirValueBuffer) 136 | { 137 | uint32_t ret; 138 | uint32_t ordinal_no = htonl(TPM_ORD_DirRead); 139 | STACK_TPM_BUFFER(tpmdata) 140 | uint32_t dirIndex_no = htonl(dirIndex); 141 | 142 | ret = TSS_buildbuff("00 c1 T l l",&tpmdata, 143 | ordinal_no, 144 | dirIndex_no); 145 | if ((ret & ERR_MASK)) { 146 | return ret; 147 | } 148 | 149 | ret = TPM_Transmit(&tpmdata,"DirRead"); 150 | 151 | if (ret != 0) { 152 | return ret; 153 | } 154 | 155 | if (tpmdata.used != 30) { 156 | ret = ERR_BAD_RESP; 157 | } 158 | 159 | if (NULL != dirValueBuffer) { 160 | memcpy(dirValueBuffer, 161 | &tpmdata.buffer[TPM_DATA_OFFSET], 162 | 20); 163 | } 164 | 165 | return ret; 166 | } 167 | -------------------------------------------------------------------------------- /libtpm/eviction.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Eviction Routines */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: eviction.c 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #include 41 | #include 42 | #include 43 | #ifdef TPM_POSIX 44 | #include 45 | #endif 46 | #ifdef TPM_WINDOWS 47 | #include 48 | #endif 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | uint32_t TPM_FlushSpecific(uint32_t handle, 58 | uint32_t resourceType) 59 | { 60 | uint32_t ret; 61 | uint32_t ordinal_no = htonl(TPM_ORD_FlushSpecific); 62 | uint32_t handle_no = htonl(handle); 63 | uint32_t resourceType_no = htonl(resourceType); 64 | STACK_TPM_BUFFER(tpmdata) 65 | 66 | #if 0 67 | if (resourceType == TPM_RT_KEY) { 68 | ret = needKeysRoom(handle, 0, 0, 0); 69 | if (ret != 0) { 70 | return ret; 71 | } 72 | } 73 | #endif 74 | 75 | ret = TSS_buildbuff("00 c1 T l l l",&tpmdata, 76 | ordinal_no, 77 | handle_no, 78 | resourceType_no); 79 | if ((ret & ERR_MASK)) { 80 | return ret; 81 | } 82 | 83 | ret = TPM_Transmit(&tpmdata,"FlushSpecific"); 84 | 85 | return ret; 86 | } 87 | -------------------------------------------------------------------------------- /libtpm/hmac.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM HMAC */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: hmac.h 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #ifndef HMAC_H 41 | #define HMAC_H 42 | 43 | #include 44 | 45 | uint32_t TSS_authhmac(unsigned char *digest, unsigned char *key, unsigned int keylen, 46 | unsigned char *h1, unsigned char *h2, unsigned char h3,...); 47 | uint32_t TSS_checkhmac1(const struct tpm_buffer *tb, uint32_t command, unsigned char *ononce, 48 | unsigned char *key, unsigned int keylen, ...); 49 | uint32_t TSS_checkhmac1New(const struct tpm_buffer *tb, uint32_t command, session *sess, unsigned char *ononce, 50 | unsigned char *key, unsigned int keylen, ...); 51 | uint32_t TSS_checkhmac2(const struct tpm_buffer *tb, uint32_t command, 52 | unsigned char *ononce1, 53 | unsigned char *key1, unsigned int keylen1, 54 | unsigned char *ononce2, 55 | unsigned char *key2, unsigned int keylen2, ...); 56 | uint32_t TSS_rawhmac(unsigned char *digest, const unsigned char *key, unsigned int keylen, ...); 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /libtpm/management.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Administrative Routines */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: management.c 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #include 41 | #include 42 | #include 43 | #ifdef TPM_POSIX 44 | #include 45 | #endif 46 | #ifdef TPM_WINDOWS 47 | #include 48 | #endif 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | 58 | uint32_t TPM_SetRedirection(uint32_t keyhandle, 59 | uint32_t redirCmd, 60 | unsigned char * inputData, uint32_t inputDataSize, 61 | unsigned char * ownerAuth, 62 | unsigned char * usageAuth) 63 | { 64 | uint32_t ret = 0; 65 | STACK_TPM_BUFFER(tpmdata) 66 | unsigned char nonceodd[TPM_HASH_SIZE]; /* odd nonce */ 67 | unsigned char authdata[TPM_HASH_SIZE]; /* auth data */ 68 | session sess; 69 | uint32_t ordinal_no = htonl(TPM_ORD_SetRedirection); 70 | uint32_t redirCmd_no = htonl(redirCmd); 71 | uint32_t inputDataSize_no = htonl(inputDataSize); 72 | uint32_t keyHandle_no = htonl(keyhandle); 73 | TPM_BOOL c = FALSE; 74 | (void)usageAuth; 75 | 76 | ret = needKeysRoom(keyhandle, 0, 0, 0); 77 | if (ret != 0) { 78 | return ret; 79 | } 80 | 81 | /* generate the odd nonce */ 82 | ret = TSS_gennonce(nonceodd); 83 | if (ret == 0) 84 | return ret; 85 | 86 | /* initiate the OSAP protocol */ 87 | ret = TSS_SessionOpen(SESSION_DSAP|SESSION_OSAP,&sess,ownerAuth,TPM_ET_OWNER,keyhandle); 88 | if (ret != 0) { 89 | return ret; 90 | } 91 | /* calculate the Authorization Data */ 92 | ret = TSS_authhmac(authdata,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE,TSS_Session_GetENonce(&sess),nonceodd,0, 93 | TPM_U32_SIZE,&ordinal_no, 94 | TPM_U32_SIZE,&redirCmd_no, 95 | TPM_U32_SIZE,&inputDataSize_no, 96 | inputDataSize, inputData, 97 | 0,0); 98 | if (ret != 0) { 99 | TSS_SessionClose(&sess); 100 | return ret; 101 | } 102 | 103 | /* insert all the calculated fields into the request buffer */ 104 | ret = TSS_buildbuff("00 c2 T l l l @ L % o %",&tpmdata, 105 | ordinal_no, 106 | keyHandle_no, 107 | redirCmd_no, 108 | inputDataSize, inputData, 109 | TSS_Session_GetHandle(&sess), 110 | TPM_HASH_SIZE, nonceodd, 111 | c, 112 | TPM_HASH_SIZE, authdata); 113 | if ((ret & ERR_MASK)) { 114 | TSS_SessionClose(&sess); 115 | return ret; 116 | } 117 | /* transmit the request buffer to the TPM device and read the reply */ 118 | ret = TPM_Transmit(&tpmdata,"SetRedirection"); 119 | TSS_SessionClose(&sess); 120 | if (ret != 0) { 121 | return ret; 122 | } 123 | 124 | ret = TSS_checkhmac1(&tpmdata,ordinal_no,nonceodd,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE, 125 | 0,0); 126 | 127 | return ret; 128 | } 129 | 130 | uint32_t TPM_ResetLockValue(unsigned char * ownerAuth) 131 | { 132 | STACK_TPM_BUFFER(tpmdata) 133 | uint32_t ordinal_no = htonl(TPM_ORD_ResetLockValue); 134 | uint32_t ret; 135 | 136 | /* check input arguments */ 137 | 138 | unsigned char nonceodd[TPM_NONCE_SIZE]; 139 | unsigned char authdata[TPM_NONCE_SIZE]; 140 | TPM_BOOL c = 0; 141 | session sess; 142 | 143 | 144 | /* generate odd nonce */ 145 | ret = TSS_gennonce(nonceodd); 146 | if (0 == ret) 147 | return ERR_CRYPT_ERR; 148 | 149 | /* Open OIAP Session */ 150 | ret = TSS_SessionOpen(SESSION_DSAP|SESSION_OSAP|SESSION_OIAP, 151 | &sess, 152 | ownerAuth, TPM_ET_OWNER, 0); 153 | 154 | if (ret != 0) 155 | return ret; 156 | 157 | /* move Network byte order data to variable for hmac calculation */ 158 | ret = TSS_authhmac(authdata,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE,TSS_Session_GetENonce(&sess),nonceodd,c, 159 | TPM_U32_SIZE,&ordinal_no, 160 | 0,0); 161 | 162 | if (0 != ret) { 163 | TSS_SessionClose(&sess); 164 | return ret; 165 | } 166 | /* build the request buffer */ 167 | ret = TSS_buildbuff("00 c2 T l L % o %", &tpmdata, 168 | ordinal_no, 169 | TSS_Session_GetHandle(&sess), 170 | TPM_HASH_SIZE, nonceodd, 171 | c, 172 | TPM_HASH_SIZE, authdata); 173 | 174 | 175 | if ((ret & ERR_MASK) != 0) { 176 | TSS_SessionClose(&sess); 177 | return ret; 178 | } 179 | 180 | /* transmit the request buffer to the TPM device and read the reply */ 181 | ret = TPM_Transmit(&tpmdata,"ResetLockValue"); 182 | TSS_SessionClose(&sess); 183 | 184 | if (ret != 0) { 185 | return ret; 186 | } 187 | /* check the HMAC in the response */ 188 | ret = TSS_checkhmac1(&tpmdata,ordinal_no,nonceodd,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE, 189 | 0,0); 190 | 191 | return ret; 192 | } 193 | -------------------------------------------------------------------------------- /libtpm/oiaposap.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Session Routines */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: oiaposap.h 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #ifndef OIAPOSAP_H 41 | #define OIAPOSAP_H 42 | #include 43 | #include 44 | 45 | typedef struct osapsess 46 | { 47 | uint32_t handle; 48 | unsigned char enonce[TPM_NONCE_SIZE]; 49 | unsigned char enonceOSAP[TPM_NONCE_SIZE]; 50 | unsigned char ononceOSAP[TPM_NONCE_SIZE]; 51 | unsigned char ssecret[TPM_HASH_SIZE]; 52 | unsigned char ononce[TPM_NONCE_SIZE]; 53 | uint16_t etype; 54 | } osapsess; 55 | 56 | typedef struct dsapsess 57 | { 58 | uint32_t handle; 59 | unsigned char enonce[TPM_NONCE_SIZE]; 60 | unsigned char enonceDSAP[TPM_NONCE_SIZE]; 61 | unsigned char ononceDSAP[TPM_NONCE_SIZE]; 62 | unsigned char ssecret[TPM_HASH_SIZE]; 63 | unsigned char ononce[TPM_NONCE_SIZE]; 64 | uint16_t etype; 65 | } dsapsess; 66 | 67 | typedef struct oiapsess 68 | { 69 | uint32_t handle; 70 | unsigned char enonce[TPM_NONCE_SIZE]; 71 | } oiapsess; 72 | 73 | typedef struct transess 74 | { 75 | uint32_t handle; 76 | unsigned char enonce[TPM_NONCE_SIZE]; 77 | } transess; 78 | 79 | typedef struct session 80 | { 81 | uint32_t sess_type; // see below 82 | union { 83 | oiapsess oiap; 84 | osapsess osap; 85 | dsapsess dsap; 86 | transess tran; 87 | } type; 88 | unsigned char authdata[TPM_AUTHDATA_SIZE]; 89 | } session; 90 | 91 | 92 | #define SESSION_OIAP 1 93 | #define SESSION_OSAP 2 94 | #define SESSION_DSAP 4 95 | #define SESSION_TRAN 8 96 | #define SESSION_DAA 16 97 | 98 | uint32_t TSS_HANDclose(uint32_t handle, TPM_RESOURCE_TYPE); 99 | uint32_t TSS_OIAPopen(uint32_t *handle, unsigned char *enonce); 100 | uint32_t TSS_OIAPclose(uint32_t handle); 101 | uint32_t TSS_OSAPopen(osapsess *sess,const unsigned char *key, uint16_t etype, uint32_t evalue); 102 | uint32_t TSS_OSAPclose(osapsess *sess); 103 | uint32_t TSS_DSAPopen(dsapsess *sess, 104 | unsigned char *key, 105 | uint16_t etype, 106 | uint32_t keyhandle, 107 | unsigned char * evalue, uint32_t evalueSize); 108 | uint32_t TSS_DSAPclose(dsapsess *sess); 109 | 110 | uint32_t TSS_SessionOpen(uint32_t allowed_type, 111 | session * sess, 112 | unsigned char *passHash, uint16_t etype, uint32_t evalue); 113 | uint32_t TSS_SessionClose(session * sess); 114 | uint32_t TSS_Session_CreateTransport(session *sess, 115 | unsigned char *transAuth, 116 | uint32_t transHandle, 117 | unsigned char *transNonce); 118 | unsigned char * TSS_Session_GetAuth(session * sess); 119 | unsigned char * TSS_Session_GetENonce(session * sess); 120 | void TSS_Session_SetENonce(session * sess, const unsigned char *enonce); 121 | uint32_t TSS_Session_GetHandle(session * sess); 122 | 123 | #endif 124 | -------------------------------------------------------------------------------- /libtpm/optin.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Testing Routines */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: optin.c 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #include 41 | #include 42 | #include 43 | #ifdef TPM_POSIX 44 | #include 45 | #endif 46 | #ifdef TPM_WINDOWS 47 | #include 48 | #endif 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | uint32_t TPM_SetOwnerInstall(TPM_BOOL state) 58 | { 59 | uint32_t ret; 60 | uint32_t ordinal_no = htonl(TPM_ORD_SetOwnerInstall); 61 | STACK_TPM_BUFFER(tpmdata) 62 | 63 | ret = TSS_buildbuff("00 c1 T l o",&tpmdata, 64 | ordinal_no, 65 | state); 66 | if ((ret & ERR_MASK)) { 67 | return ret; 68 | } 69 | 70 | ret = TPM_Transmit(&tpmdata,"SetOwnerInstall"); 71 | 72 | if (ret == 0 && tpmdata.used != 10) { 73 | ret = ERR_BAD_RESP; 74 | } 75 | 76 | return ret; 77 | } 78 | 79 | 80 | uint32_t TPM_OwnerSetDisable(unsigned char *ownerauth, 81 | TPM_BOOL state) 82 | { 83 | STACK_TPM_BUFFER(tpmdata) 84 | unsigned char nonceodd[TPM_NONCE_SIZE]; 85 | unsigned char authdata[TPM_NONCE_SIZE]; 86 | unsigned char c = 0; 87 | uint32_t ordinal_no = htonl(TPM_ORD_OwnerSetDisable); 88 | uint32_t ret; 89 | session sess; 90 | 91 | /* check input arguments */ 92 | if (NULL == ownerauth) return ERR_NULL_ARG; 93 | 94 | 95 | /* generate odd nonce */ 96 | ret = TSS_gennonce(nonceodd); 97 | if (0 == ret) 98 | return ERR_CRYPT_ERR; 99 | 100 | /* Open Session */ 101 | ret = TSS_SessionOpen(SESSION_DSAP|SESSION_OSAP|SESSION_OIAP, 102 | &sess, 103 | ownerauth, TPM_ET_OWNER, 0); 104 | if (ret != 0) 105 | return ret; 106 | 107 | 108 | /* move Network byte order data to variable for hmac calculation */ 109 | ret = TSS_authhmac(authdata,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE,TSS_Session_GetENonce(&sess),nonceodd,c, 110 | TPM_U32_SIZE,&ordinal_no, 111 | sizeof(TPM_BOOL),&state, 112 | 0,0); 113 | 114 | if (0 != ret) { 115 | TSS_SessionClose(&sess); 116 | return ret; 117 | } 118 | /* build the request buffer */ 119 | ret = TSS_buildbuff("00 c2 T l o L % o %", &tpmdata, 120 | ordinal_no, 121 | state, 122 | TSS_Session_GetHandle(&sess), 123 | TPM_NONCE_SIZE,nonceodd, 124 | c, 125 | TPM_HASH_SIZE,authdata); 126 | if ((ret & ERR_MASK)) { 127 | TSS_SessionClose(&sess); 128 | return ret; 129 | } 130 | /* transmit the request buffer to the TPM device and read the reply */ 131 | ret = TPM_Transmit(&tpmdata,"OwnerSetDisable"); 132 | TSS_SessionClose(&sess); 133 | 134 | if (ret != 0) { 135 | return ret; 136 | } 137 | /* check the HMAC in the response */ 138 | 139 | ret = TSS_checkhmac1(&tpmdata,ordinal_no,nonceodd,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE, 140 | 0,0); 141 | 142 | return ret; 143 | } 144 | 145 | 146 | uint32_t TPM_SetTempDeactivated(unsigned char *operatorauth // HMAC key 147 | ) 148 | { 149 | STACK_TPM_BUFFER(tpmdata) 150 | unsigned char nonceodd[TPM_NONCE_SIZE]; 151 | unsigned char authdata[TPM_NONCE_SIZE]; 152 | unsigned char c = 0; 153 | uint32_t ordinal_no = htonl(TPM_ORD_SetTempDeactivated); 154 | uint32_t ret; 155 | 156 | /* check input arguments */ 157 | 158 | 159 | if (NULL != operatorauth) { 160 | /* Open OIAP Session */ 161 | session sess; 162 | ret = TSS_SessionOpen(SESSION_OSAP|SESSION_OIAP, 163 | &sess, 164 | operatorauth, TPM_ET_OWNER, 0); 165 | if (ret != 0) 166 | return ret; 167 | /* calculate encrypted authorization value */ 168 | 169 | /* generate odd nonce */ 170 | ret = TSS_gennonce(nonceodd); 171 | if (0 == ret) 172 | return ERR_CRYPT_ERR; 173 | ret = TSS_authhmac(authdata,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE,TSS_Session_GetENonce(&sess),nonceodd,c, 174 | TPM_U32_SIZE,&ordinal_no, 175 | 0,0); 176 | 177 | if (0 != ret) { 178 | TSS_SessionClose(&sess); 179 | return ret; 180 | } 181 | /* build the request buffer */ 182 | ret = TSS_buildbuff("00 c1 T l L % o %", &tpmdata, 183 | ordinal_no, 184 | TSS_Session_GetHandle(&sess), 185 | TPM_NONCE_SIZE,nonceodd, 186 | c, 187 | TPM_HASH_SIZE,authdata); 188 | if ((ret & ERR_MASK)) { 189 | TSS_SessionClose(&sess); 190 | return ret; 191 | } 192 | /* transmit the request buffer to the TPM device and read the reply */ 193 | ret = TPM_Transmit(&tpmdata,"SetTempDeactivated - AUTH1"); 194 | 195 | TSS_SessionClose(&sess); 196 | if (ret != 0) { 197 | return ret; 198 | } 199 | 200 | /* check the HMAC in the response */ 201 | 202 | ret = TSS_checkhmac1(&tpmdata,ordinal_no,nonceodd,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE, 203 | 0,0); 204 | } else { 205 | /* build the request buffer */ 206 | ret = TSS_buildbuff("00 c1 T l", &tpmdata, 207 | ordinal_no); 208 | 209 | /* transmit the request buffer to the TPM device and read the reply */ 210 | ret = TPM_Transmit(&tpmdata,"SetTempDeactivated"); 211 | } 212 | 213 | return ret; 214 | } 215 | 216 | 217 | 218 | uint32_t TPM_PhysicalEnable() 219 | { 220 | uint32_t ret; 221 | uint32_t ordinal_no = htonl(TPM_ORD_PhysicalEnable); 222 | STACK_TPM_BUFFER(tpmdata) 223 | 224 | ret = TSS_buildbuff("00 c1 T l",&tpmdata, 225 | ordinal_no); 226 | if ((ret & ERR_MASK)) { 227 | return ret; 228 | } 229 | 230 | ret = TPM_Transmit(&tpmdata,"PhysicalEnable"); 231 | 232 | if (ret == 0 && tpmdata.used != 10) { 233 | ret = ERR_BAD_RESP; 234 | } 235 | 236 | return ret; 237 | } 238 | 239 | uint32_t TPM_PhysicalDisable() 240 | { 241 | uint32_t ret; 242 | uint32_t ordinal_no = htonl(TPM_ORD_PhysicalDisable); 243 | STACK_TPM_BUFFER(tpmdata) 244 | 245 | ret = TSS_buildbuff("00 c1 T l",&tpmdata, 246 | ordinal_no); 247 | if ((ret & ERR_MASK)) { 248 | return ret; 249 | } 250 | 251 | ret = TPM_Transmit(&tpmdata,"PhysicalDisable"); 252 | 253 | if (ret == 0 && tpmdata.used != 10) { 254 | ret = ERR_BAD_RESP; 255 | } 256 | 257 | return ret; 258 | } 259 | 260 | 261 | uint32_t TPM_PhysicalSetDeactivated(TPM_BOOL state) 262 | { 263 | uint32_t ret; 264 | uint32_t ordinal_no = htonl(TPM_ORD_PhysicalSetDeactivated); 265 | STACK_TPM_BUFFER(tpmdata) 266 | 267 | ret = TSS_buildbuff("00 c1 T l o",&tpmdata, 268 | ordinal_no, 269 | state); 270 | if ((ret & ERR_MASK)) { 271 | return ret; 272 | } 273 | 274 | ret = TPM_Transmit(&tpmdata,"PhysicalSetDeactivated"); 275 | 276 | if (ret == 0 && tpmdata.used != 10) { 277 | ret = ERR_BAD_RESP; 278 | } 279 | 280 | return ret; 281 | } 282 | 283 | 284 | uint32_t TPM_SetOperatorAuth(unsigned char * operatorAuth) 285 | { 286 | uint32_t ret; 287 | uint32_t ordinal_no = htonl(TPM_ORD_SetOperatorAuth); 288 | STACK_TPM_BUFFER(tpmdata) 289 | 290 | if (NULL == operatorAuth) return ERR_NULL_ARG; 291 | 292 | ret = TSS_buildbuff("00 c1 T l %",&tpmdata, 293 | ordinal_no, 294 | TPM_HASH_SIZE, operatorAuth); 295 | if ((ret & ERR_MASK)) { 296 | return ret; 297 | } 298 | 299 | ret = TPM_Transmit(&tpmdata,"SetOperatorAuth"); 300 | 301 | if (ret == 0 && tpmdata.used != 10) { 302 | ret = ERR_BAD_RESP; 303 | } 304 | 305 | return ret; 306 | } 307 | -------------------------------------------------------------------------------- /libtpm/pcrs.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM PCR Routines */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: pcrs.h 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #ifndef PCRS_H 41 | #define PCRS_H 42 | 43 | #define TPM_PCR_NUM 16 /* number of PCR registers supported */ 44 | #define TPM_PCR_MASK_SIZE 2 /* size in bytes of PCR bit mask */ 45 | 46 | uint32_t TPM_PcrRead(uint32_t pcrindex, unsigned char *pcrvalue); 47 | //uint32_t TSS_GenPCRInfo(uint32_t pcrmap, unsigned char *pcrinfo, unsigned int *len); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /libtpm/raw.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Test Routines to detect bugs */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: raw.c 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #include 41 | #include 42 | #include 43 | #ifdef TPM_POSIX 44 | #include 45 | #endif 46 | #ifdef TPM_WINDOWS 47 | #include 48 | #endif 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | 58 | uint32_t TPM_RawDataRaw(uint32_t ordinal, 59 | unsigned char * data, 60 | uint32_t datalen) 61 | { 62 | STACK_TPM_BUFFER(tpmdata) 63 | uint32_t ordinal_no = ntohl(ordinal); 64 | uint32_t ret; 65 | 66 | ret = TSS_buildbuff("00 c1 T l %", &tpmdata, 67 | ordinal_no, 68 | datalen, data); 69 | 70 | if ((ret & ERR_MASK)) { 71 | return ret; 72 | } 73 | 74 | ret = TPM_Transmit(&tpmdata,"* RawData - Raw *"); 75 | 76 | return ret; 77 | } 78 | 79 | 80 | uint32_t TPM_RawDataOIAP(uint32_t ordinal, 81 | unsigned char * ownerauth, 82 | unsigned char * data, 83 | uint32_t datalen) 84 | { 85 | unsigned char enonce[TPM_HASH_SIZE]; 86 | unsigned char nonceodd[TPM_HASH_SIZE]; 87 | unsigned char authdata[TPM_HASH_SIZE]; 88 | STACK_TPM_BUFFER(tpmdata) 89 | unsigned char c = 0; 90 | uint32_t ordinal_no = ntohl(ordinal); 91 | uint32_t ret; 92 | uint32_t authhandle; 93 | 94 | ret = TSS_OIAPopen(&authhandle,enonce); 95 | if (ret != 0) { 96 | printf("Could not open OIAP session!\n"); 97 | return ret; 98 | } 99 | 100 | /* generate odd nonce */ 101 | ret = TSS_gennonce(nonceodd); 102 | if (0 == ret) { 103 | TSS_OIAPclose(authhandle); 104 | return ERR_CRYPT_ERR; 105 | } 106 | 107 | ret = TSS_authhmac(authdata,ownerauth,TPM_HASH_SIZE,enonce,nonceodd,c, 108 | TPM_U32_SIZE,&ordinal_no, 109 | datalen,data, 110 | 0,0); 111 | 112 | if (0 != ret) { 113 | printf("Error calculating MAC.\n"); 114 | TSS_OIAPclose(authhandle); 115 | return ret; 116 | } 117 | 118 | ret = TSS_buildbuff("00 c1 T l % l % o %", &tpmdata, 119 | ordinal_no, 120 | datalen, data, 121 | authhandle, 122 | TPM_NONCE_SIZE, nonceodd, 123 | c, 124 | TPM_HASH_SIZE,authdata); 125 | 126 | if ((ret & ERR_MASK)) { 127 | TSS_OIAPclose(authhandle); 128 | return ret; 129 | } 130 | 131 | ret = TPM_Transmit(&tpmdata,"* RawData - OIAP*"); 132 | 133 | TSS_OIAPclose(authhandle); 134 | 135 | return ret; 136 | } 137 | 138 | uint32_t TPM_RawDataOSAP(uint32_t keyhandle, 139 | uint32_t ordinal, 140 | unsigned char * ownerauth, 141 | unsigned char * data, 142 | uint32_t datalen) 143 | { 144 | unsigned char nonceodd[TPM_HASH_SIZE]; 145 | unsigned char authdata[TPM_HASH_SIZE]; 146 | STACK_TPM_BUFFER(tpmdata) 147 | unsigned char encauth[TPM_HASH_SIZE]; 148 | unsigned char dummy[TPM_HASH_SIZE]; 149 | unsigned char c = 0; 150 | uint32_t ordinal_no = ntohl(ordinal); 151 | uint32_t ret; 152 | session sess; 153 | osapsess *osap = &sess.type.osap; 154 | uint16_t keytype; 155 | unsigned char *passptr1; 156 | 157 | if (keyhandle == 0x40000000) keytype = TPM_ET_SRK; 158 | else keytype = TPM_ET_OWNER; 159 | 160 | ret = needKeysRoom(keyhandle, 0 ,0, 0); 161 | if (ret != 0) { 162 | return ret; 163 | } 164 | 165 | memset(dummy,0x0,sizeof(dummy)); 166 | 167 | if (NULL != ownerauth) 168 | passptr1 = ownerauth; 169 | else 170 | passptr1 = dummy; 171 | 172 | sess.sess_type = SESSION_OSAP; 173 | ret = TSS_OSAPopen(osap,ownerauth,keytype,keyhandle); 174 | if (ret != 0) { 175 | printf("Could not open OIAP session!\n"); 176 | return ret; 177 | } 178 | 179 | /* calculate encrypted authorization value */ 180 | TPM_CreateEncAuth(&sess, passptr1, encauth, 0); 181 | 182 | /* generate odd nonce */ 183 | ret = TSS_gennonce(nonceodd); 184 | if (0 == ret) { 185 | TSS_OSAPclose(osap); 186 | return ERR_CRYPT_ERR; 187 | } 188 | 189 | ret = TSS_authhmac(authdata,osap->ssecret,TPM_HASH_SIZE,osap->enonce,nonceodd,c, 190 | TPM_U32_SIZE,&ordinal_no, 191 | datalen,data, 192 | 0,0); 193 | 194 | if (0 != ret) { 195 | printf("Error calculating MAC.\n"); 196 | TSS_OSAPclose(osap); 197 | return ret; 198 | } 199 | 200 | ret = TSS_buildbuff("00 c1 T l % l % o %", &tpmdata, 201 | ordinal_no, 202 | datalen, data, 203 | osap->handle, 204 | TPM_NONCE_SIZE, nonceodd, 205 | c, 206 | TPM_HASH_SIZE,authdata); 207 | 208 | if ((ret & ERR_MASK)) { 209 | TSS_OSAPclose(osap); 210 | return ret; 211 | } 212 | 213 | ret = TPM_Transmit(&tpmdata,"* RawData - OIAP*"); 214 | 215 | TSS_OSAPclose(osap); 216 | 217 | return ret; 218 | } 219 | -------------------------------------------------------------------------------- /libtpm/rng.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Random Number Generator Routines */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: rng.c 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #include 41 | #include 42 | #include 43 | #ifdef TPM_POSIX 44 | #include 45 | #endif 46 | #ifdef TPM_WINDOWS 47 | #include 48 | #endif 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | 58 | /****************************************************************************/ 59 | /* */ 60 | /* Get Random Number */ 61 | /* */ 62 | /* The parameters are... */ 63 | /* */ 64 | /* numbytes : The number of bytes requested */ 65 | /* buffer : a buffer to hold the amount of requested bytes */ 66 | /* bytesret : The actual number of bytes that were returned */ 67 | /****************************************************************************/ 68 | uint32_t TPM_GetRandom(uint32_t bytesreq, 69 | unsigned char * buffer, uint32_t * bytesret) 70 | { 71 | uint32_t ret; 72 | STACK_TPM_BUFFER( tpmdata ) 73 | 74 | uint32_t ordinal_no = htonl(TPM_ORD_GetRandom); 75 | uint32_t numbytes_no = htonl(bytesreq); 76 | 77 | TSS_buildbuff("00 c1 T l l",&tpmdata, 78 | ordinal_no, 79 | numbytes_no); 80 | 81 | ret = TPM_Transmit(&tpmdata,"GetRandom"); 82 | 83 | if (0 != ret) { 84 | return ret; 85 | } 86 | 87 | ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET, bytesret); 88 | if ((ret & ERR_MASK)) { 89 | return ret; 90 | } 91 | memcpy(buffer, 92 | &tpmdata.buffer[TPM_DATA_OFFSET + TPM_U32_SIZE], 93 | *bytesret); 94 | 95 | return ret; 96 | } 97 | 98 | 99 | 100 | /****************************************************************************/ 101 | /* */ 102 | /* Stir Random Number Generator */ 103 | /* */ 104 | /* The parameters are... */ 105 | /* */ 106 | /* data : Data to add entropy to the random number generator's state */ 107 | /* datalen : The number of bytes; must be < 256 */ 108 | /****************************************************************************/ 109 | uint32_t TPM_StirRandom(unsigned char * data, uint32_t datalen) 110 | { 111 | uint32_t ret; 112 | STACK_TPM_BUFFER(tpmdata) 113 | uint32_t ordinal_no = htonl(TPM_ORD_StirRandom); 114 | 115 | TSS_buildbuff("00 c1 T l @",&tpmdata, 116 | ordinal_no, 117 | (datalen & 0xff), data); 118 | 119 | ret = TPM_Transmit(&tpmdata,"StirRandom"); 120 | return ret; 121 | } 122 | 123 | -------------------------------------------------------------------------------- /libtpm/session.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Session Routines */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: session.c 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #include 41 | #include 42 | #include 43 | #ifdef TPM_POSIX 44 | #include 45 | #endif 46 | #ifdef TPM_WINDOWS 47 | #include 48 | #endif 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | uint32_t TPM_KeyControlOwner( 58 | unsigned char *ownerauth, // HMAC key 59 | uint32_t keyhandle, 60 | keydata *pubkey, 61 | uint32_t bitname, 62 | TPM_BOOL bitvalue 63 | ) 64 | { 65 | STACK_TPM_BUFFER( tpmdata ) 66 | unsigned char nonceodd[TPM_NONCE_SIZE]; 67 | unsigned char authdata[TPM_NONCE_SIZE]; 68 | unsigned char c = 0; 69 | uint32_t ordinal_no = htonl(TPM_ORD_KeyControlOwner); 70 | uint32_t ret; 71 | uint32_t bitname_no = ntohl(bitname); 72 | uint32_t keyhandle_no = ntohl(keyhandle); 73 | session sess; 74 | 75 | STACK_TPM_BUFFER(serPubKey) 76 | 77 | /* check input arguments */ 78 | if (NULL == ownerauth) 79 | return ERR_NULL_ARG; 80 | 81 | ret = needKeysRoom(keyhandle, 0, 0, 0); 82 | if (ret != 0) { 83 | return ret; 84 | } 85 | 86 | ret = TPM_WriteKeyPub(&serPubKey, pubkey); 87 | if ((ret & ERR_MASK) != 0) { 88 | return ret; 89 | } 90 | 91 | /* generate odd nonce */ 92 | ret = TSS_gennonce(nonceodd); 93 | if (0 == ret) 94 | return ERR_CRYPT_ERR; 95 | 96 | /* Open OSAP Session */ 97 | ret = TSS_SessionOpen(SESSION_OSAP|SESSION_OIAP, 98 | &sess, 99 | ownerauth, TPM_ET_OWNER, 0); 100 | if (ret != 0) 101 | return ret; 102 | /* calculate encrypted authorization value */ 103 | 104 | ret = TSS_authhmac(authdata,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE,TSS_Session_GetENonce(&sess),nonceodd,c, 105 | TPM_U32_SIZE,&ordinal_no, 106 | serPubKey.used, serPubKey.buffer, 107 | sizeof(uint32_t),&bitname_no, 108 | sizeof(TPM_BOOL), &bitvalue, 109 | 0,0); 110 | 111 | if (0 != ret) { 112 | TSS_SessionClose(&sess); 113 | return ret; 114 | } 115 | /* build the request buffer */ 116 | ret = TSS_buildbuff("00 c2 T l l % l o L % o %", &tpmdata, 117 | ordinal_no, 118 | keyhandle_no, 119 | serPubKey.used, serPubKey.buffer, 120 | bitname_no, 121 | bitvalue, 122 | TSS_Session_GetHandle(&sess), 123 | TPM_NONCE_SIZE,nonceodd, 124 | c, 125 | TPM_HASH_SIZE,authdata); 126 | if ((ret & ERR_MASK)) { 127 | TSS_SessionClose(&sess); 128 | return ret; 129 | } 130 | /* transmit the request buffer to the TPM device and read the reply */ 131 | ret = TPM_Transmit(&tpmdata,"KeyControlOwner - AUTH1"); 132 | TSS_SessionClose(&sess); 133 | 134 | if (ret != 0) { 135 | return ret; 136 | } 137 | /* check the HMAC in the response */ 138 | 139 | ret = TSS_checkhmac1(&tpmdata,ordinal_no,nonceodd,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE, 140 | 0,0); 141 | 142 | return ret; 143 | } 144 | 145 | static uint32_t TPM_SaveContext_Internal(uint32_t handle, 146 | uint32_t resourceType, 147 | char * label, 148 | struct tpm_buffer *context, 149 | int allowTransport) 150 | { 151 | uint32_t ret; 152 | uint32_t ordinal_no = htonl(TPM_ORD_SaveContext); 153 | STACK_TPM_BUFFER(tpmdata) 154 | uint32_t resourceType_no = htonl(resourceType); 155 | uint32_t handle_no = htonl(handle); 156 | uint32_t len; 157 | 158 | ret = TSS_buildbuff("00 c1 T l l l %",&tpmdata, 159 | ordinal_no, 160 | handle_no, 161 | resourceType_no, 162 | 16, label); 163 | if ( ( ret & ERR_MASK ) != 0) { 164 | goto exit; 165 | } 166 | 167 | if (allowTransport) 168 | ret = TPM_Transmit(&tpmdata,"SaveContext"); 169 | else 170 | ret = TPM_Transmit_NoTransport(&tpmdata, "SaveContext"); 171 | 172 | if (0 != ret) { 173 | goto exit; 174 | } 175 | 176 | ret = tpm_buffer_load32(&tpmdata, 177 | TPM_DATA_OFFSET, 178 | &len); 179 | if ((ret & ERR_MASK)) { 180 | return ret; 181 | } 182 | 183 | if (context) { 184 | SET_TPM_BUFFER(context, 185 | &tpmdata.buffer[TPM_DATA_OFFSET+TPM_U32_SIZE], 186 | len); 187 | } 188 | 189 | if (TPM_DATA_OFFSET + TPM_U32_SIZE + len != tpmdata.used) { 190 | printf("Something is wrong with the context blob!\n"); 191 | } 192 | 193 | exit: 194 | return ret; 195 | } 196 | 197 | 198 | uint32_t TPM_SaveContext_UseRoom(uint32_t handle, 199 | uint32_t resourceType, 200 | char * label, 201 | struct tpm_buffer *context) 202 | { 203 | uint32_t ret; 204 | 205 | /* 206 | * Typically we would run the following code here: 207 | * 208 | * uint32_t replaced_keyhandle = 0; 209 | * 210 | * if (resourceType == TPM_RT_KEY) { 211 | * ret = needKeysRoom_Stacked(handle, &replaced_keyhandle); 212 | * if (ret != 0) 213 | * return ret; 214 | * } 215 | * 216 | * But that creates a lot of problems due to occurring recursion, 217 | * so for this comamnd we need to assume that the handle is 218 | * in the TPM at the moment. 219 | */ 220 | 221 | ret = TPM_SaveContext_Internal(handle, 222 | resourceType, 223 | label, 224 | context, 225 | 0); 226 | 227 | 228 | /* 229 | * Also don't need to do this here: 230 | * 231 | * if (resourceType == TPM_RT_KEY) 232 | * needKeysRoom_Stacked_Undo(0, replaced_keyhandle); 233 | */ 234 | return ret; 235 | } 236 | 237 | 238 | uint32_t TPM_SaveContext(uint32_t handle, 239 | uint32_t resourceType, 240 | char * label, 241 | struct tpm_buffer *context) 242 | { 243 | uint32_t ret; 244 | 245 | if (resourceType == TPM_RT_KEY) { 246 | ret = needKeysRoom(handle, 0, 0, 0); 247 | if (ret != 0) 248 | return ret; 249 | } 250 | 251 | return TPM_SaveContext_Internal(handle, 252 | resourceType, 253 | label, 254 | context, 255 | 1); 256 | } 257 | 258 | 259 | 260 | 261 | uint32_t TPM_LoadContext(uint32_t entityHandle, 262 | TPM_BOOL keephandle, 263 | struct tpm_buffer *context, 264 | uint32_t * handle) 265 | { 266 | uint32_t ret; 267 | uint32_t ordinal_no = htonl(TPM_ORD_LoadContext); 268 | STACK_TPM_BUFFER(tpmdata) 269 | uint32_t entityHandle_no = htonl(entityHandle); 270 | 271 | /* 272 | * must not call needKeysRoom from this function here 273 | * otherwise I might end up in an endless loop!!! 274 | */ 275 | 276 | ret = TSS_buildbuff("00 c1 T l l o @",&tpmdata, 277 | ordinal_no, 278 | entityHandle_no, 279 | keephandle, 280 | context->used, context->buffer); 281 | if ((ret & ERR_MASK)) { 282 | goto exit; 283 | } 284 | 285 | ret = TPM_Transmit(&tpmdata,"LoadContext"); 286 | 287 | if (0 != ret) { 288 | goto exit; 289 | } 290 | 291 | ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET, handle); 292 | exit: 293 | return ret; 294 | } 295 | -------------------------------------------------------------------------------- /libtpm/sha.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM SHA Digest Routines */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: sha.c 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #include 41 | #include 42 | #include 43 | #ifdef TPM_POSIX 44 | #include 45 | #endif 46 | #ifdef TPM_WINDOWS 47 | #include 48 | #endif 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | /****************************************************************************/ 58 | /* */ 59 | /* Start a SHA1 Digest */ 60 | /* */ 61 | /****************************************************************************/ 62 | uint32_t TPM_SHA1Start(uint32_t *maxNumBytes) { 63 | uint32_t ordinal_no; 64 | uint32_t ret; 65 | STACK_TPM_BUFFER(tpmdata) 66 | /* move Network byte order data to variable for hmac calculation */ 67 | ordinal_no = htonl(TPM_ORD_SHA1Start); 68 | 69 | TSS_buildbuff("00 c1 T l", &tpmdata, 70 | ordinal_no); 71 | /* transmit the request buffer to the TPM device and read the reply */ 72 | ret = TPM_Transmit(&tpmdata,"SHA1Start"); 73 | 74 | if (ret != 0) { 75 | return ret; 76 | } 77 | 78 | ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET, maxNumBytes); 79 | 80 | return ret; 81 | } 82 | 83 | /****************************************************************************/ 84 | /* */ 85 | /* Do a SHA1 Update */ 86 | /* */ 87 | /* The arguments are ... */ 88 | /* */ 89 | /* data : A block of data whose size must be a multiple of 64 */ 90 | /* datalen : The length of the data block */ 91 | /****************************************************************************/ 92 | uint32_t TPM_SHA1Update(void * data, uint32_t datalen) { 93 | uint32_t ordinal_no; 94 | uint32_t ret; 95 | struct tpm_buffer *tpmdata = TSS_AllocTPMBuffer(datalen+20); 96 | /* move Network byte order data to variable for hmac calculation */ 97 | ordinal_no = htonl(TPM_ORD_SHA1Update); 98 | 99 | if (NULL == tpmdata) { 100 | return ERR_BAD_SIZE; 101 | } 102 | 103 | ret = TSS_buildbuff("00 c1 T l @", tpmdata, 104 | ordinal_no, 105 | datalen, data); 106 | if (ret & ERR_MASK) { 107 | goto err_exit; 108 | } 109 | /* transmit the request buffer to the TPM device and read the reply */ 110 | ret = TPM_Transmit(tpmdata,"SHA1Update"); 111 | 112 | err_exit: 113 | TSS_FreeTPMBuffer(tpmdata); 114 | 115 | return ret; 116 | } 117 | 118 | /****************************************************************************/ 119 | /* */ 120 | /* Do a SHA1 Complete */ 121 | /* */ 122 | /* The arguments are ... */ 123 | /* */ 124 | /* data : A block of data whose size must be 64 or less */ 125 | /* datalen : The length of the data block */ 126 | /* hash : A block of size TPM_HASH_SIZE (=20) to hold the SHA1 hash */ 127 | /****************************************************************************/ 128 | uint32_t TPM_SHA1Complete(void *data, uint32_t datalen, 129 | unsigned char * hash) { 130 | uint32_t ordinal_no; 131 | uint32_t ret; 132 | STACK_TPM_BUFFER(tpmdata) 133 | 134 | /* move Network byte order data to variable for hmac calculation */ 135 | ordinal_no = htonl(TPM_ORD_SHA1Complete); 136 | 137 | TSS_buildbuff("00 c1 T l @", &tpmdata, 138 | ordinal_no, 139 | datalen, data); 140 | 141 | /* transmit the request buffer to the TPM device and read the reply */ 142 | ret = TPM_Transmit(&tpmdata,"SHA1Complete"); 143 | 144 | if (0 != ret) { 145 | return ret; 146 | } 147 | 148 | memcpy(hash, 149 | &tpmdata.buffer[TPM_DATA_OFFSET], 150 | TPM_HASH_SIZE); 151 | return ret; 152 | } 153 | 154 | /****************************************************************************/ 155 | /* */ 156 | /* Do a SHA1 Complete Extend */ 157 | /* */ 158 | /* The arguments are ... */ 159 | /* */ 160 | /* data : A block of data whose size must be 64 or less */ 161 | /* datalen : The length of the data block */ 162 | /* pcrNum : The index of the CPR to be modified */ 163 | /* hash : A block of size TPM_HASH_SIZE (=20) to hold the SHA1 hash */ 164 | /* pcrValue : A block of size TPM_HASH_SIZE (=20) to hold the PCR value */ 165 | /****************************************************************************/ 166 | uint32_t TPM_SHA1CompleteExtend(void *data, uint32_t datalen, 167 | uint32_t pcrNum, 168 | unsigned char * hash, 169 | unsigned char * pcrValue) 170 | { 171 | uint32_t ordinal_no; 172 | uint32_t pcrNum_no = htonl(pcrNum); 173 | uint32_t ret; 174 | STACK_TPM_BUFFER(tpmdata) 175 | 176 | /* move Network byte order data to variable for hmac calculation */ 177 | ordinal_no = htonl(TPM_ORD_SHA1CompleteExtend); 178 | 179 | TSS_buildbuff("00 c1 T l l @", &tpmdata, 180 | ordinal_no, 181 | pcrNum_no, 182 | datalen, data); 183 | 184 | /* transmit the request buffer to the TPM device and read the reply */ 185 | ret = TPM_Transmit(&tpmdata,"SHA1CompleteExtend"); 186 | 187 | if (0 != ret) { 188 | return ret; 189 | } 190 | 191 | memcpy(hash, 192 | &tpmdata.buffer[TPM_DATA_OFFSET], 193 | TPM_HASH_SIZE); 194 | 195 | memcpy(pcrValue, 196 | &tpmdata.buffer[TPM_DATA_OFFSET + TPM_HASH_SIZE], 197 | TPM_HASH_SIZE); 198 | 199 | return ret; 200 | } 201 | -------------------------------------------------------------------------------- /libtpm/signature.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Signature Routines */ 4 | /* Written by J. Kravitz, S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: signature.c 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #include 41 | #include 42 | #include 43 | #ifdef TPM_POSIX 44 | #include 45 | #endif 46 | #ifdef TPM_WINDOWS 47 | #include 48 | #endif 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | 55 | 56 | /****************************************************************************/ 57 | /* */ 58 | /* Sign some data */ 59 | /* */ 60 | /* The arguments are... */ 61 | /* */ 62 | /* keyhandle is the handle of the key to sign with */ 63 | /* keyauth is the authorization data (password) for the parent key */ 64 | /* if null, it is assumed that the key has no authorization req */ 65 | /* data is a pointer to the data to be signed */ 66 | /* datalen is the length of the data being signed */ 67 | /* sig is a pointer to an area to receive the signature (<=256 bytes) */ 68 | /* siglen is a pointer to an integer to receive the signature length */ 69 | /* */ 70 | /****************************************************************************/ 71 | uint32_t TPM_Sign(uint32_t keyhandle, unsigned char *keyauth, 72 | unsigned char *data, uint32_t datalen, 73 | unsigned char *sig, uint32_t *siglen) { 74 | uint32_t ret; 75 | STACK_TPM_BUFFER(tpmdata) 76 | unsigned char nonceodd[TPM_NONCE_SIZE]; 77 | unsigned char pubauth[TPM_HASH_SIZE]; 78 | unsigned char c = 0; 79 | uint32_t ordinal = htonl(TPM_ORD_Sign); 80 | uint32_t keyhndl = htonl(keyhandle); 81 | uint32_t datasize = htonl(datalen); 82 | uint32_t sigsize; 83 | 84 | /* check input arguments */ 85 | if (data == NULL || sig == NULL) return ERR_NULL_ARG; 86 | 87 | ret = needKeysRoom(keyhandle, 0, 0, 0); 88 | if (ret != 0) { 89 | return ret; 90 | } 91 | 92 | if (keyauth != NULL) /* key requires authorization */ 93 | { 94 | session sess; 95 | /* 96 | generate odd nonce from data. This is 97 | good, but for a test suite it should 98 | be OK. I need to do this to be able to later on 99 | verify the INFO type of signature. 100 | */ 101 | TSS_sha1(data, datalen, nonceodd); 102 | 103 | /* Open OIAP Session */ 104 | ret = TSS_SessionOpen(SESSION_OSAP|SESSION_OIAP|SESSION_DSAP, 105 | &sess, 106 | keyauth, TPM_ET_KEYHANDLE, keyhandle); 107 | if (ret != 0) 108 | return ret; 109 | 110 | /* calculate authorization HMAC value */ 111 | ret = TSS_authhmac(pubauth,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE,TSS_Session_GetENonce(&sess),nonceodd,c, 112 | TPM_U32_SIZE,&ordinal, 113 | TPM_U32_SIZE,&datasize, 114 | datalen,data, 115 | 0,0); 116 | if (ret != 0) { 117 | TSS_SessionClose(&sess); 118 | return ret; 119 | } 120 | /* build the request buffer */ 121 | ret = TSS_buildbuff("00 c2 T l l @ L % o %",&tpmdata, 122 | ordinal, 123 | keyhndl, 124 | datalen,data, 125 | TSS_Session_GetHandle(&sess), 126 | TPM_NONCE_SIZE,nonceodd, 127 | c, 128 | TPM_HASH_SIZE,pubauth); 129 | if ((ret & ERR_MASK) != 0) { 130 | TSS_SessionClose(&sess); 131 | return ret; 132 | } 133 | /* transmit the request buffer to the TPM device and read the reply */ 134 | ret = TPM_Transmit(&tpmdata,"Sign"); 135 | TSS_SessionClose(&sess); 136 | if (ret != 0) { 137 | return ret; 138 | } 139 | ret = tpm_buffer_load32(&tpmdata,TPM_DATA_OFFSET, &sigsize); 140 | if ((ret & ERR_MASK)) { 141 | return ret; 142 | } 143 | /* check the HMAC in the response */ 144 | ret = TSS_checkhmac1(&tpmdata,ordinal,nonceodd,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE, 145 | TPM_U32_SIZE,TPM_DATA_OFFSET, 146 | sigsize,TPM_DATA_OFFSET+TPM_U32_SIZE, 147 | 0,0); 148 | if (ret != 0) 149 | return ret; 150 | memcpy(sig, 151 | &tpmdata.buffer[TPM_DATA_OFFSET+TPM_U32_SIZE], 152 | sigsize); 153 | *siglen = sigsize; 154 | } else /* key requires NO authorization */ { 155 | /* move Network byte order data to variables for hmac calculation */ 156 | /* build the request buffer */ 157 | ret = TSS_buildbuff("00 c1 T l l @",&tpmdata, 158 | ordinal, 159 | keyhndl, 160 | datalen,data); 161 | if ((ret & ERR_MASK) != 0) 162 | return ret; 163 | /* transmit the request buffer to the TPM device and read the reply */ 164 | ret = TPM_Transmit(&tpmdata,"Sign"); 165 | if (ret != 0) 166 | return ret; 167 | ret = tpm_buffer_load32(&tpmdata, 168 | TPM_DATA_OFFSET, 169 | &sigsize); 170 | if ((ret & ERR_MASK)) { 171 | return ret; 172 | } 173 | memcpy(sig, 174 | &tpmdata.buffer[TPM_DATA_OFFSET+TPM_U32_SIZE], 175 | sigsize); 176 | *siglen = sigsize; 177 | } 178 | return 0; 179 | } 180 | -------------------------------------------------------------------------------- /libtpm/startup.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Startup Routines */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: startup.c 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #include 41 | #include 42 | #include 43 | #ifdef TPM_POSIX 44 | #include 45 | #endif 46 | #ifdef TPM_WINDOWS 47 | #include 48 | #endif 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | uint32_t TPM_Startup(uint16_t type) 58 | { 59 | uint32_t ret; 60 | uint32_t ordinal_no = htonl(TPM_ORD_Startup); 61 | STACK_TPM_BUFFER(tpmdata) 62 | uint16_t type_no = htons(type); 63 | 64 | ret = TSS_buildbuff("00 c1 T l s",&tpmdata, 65 | ordinal_no, 66 | type_no); 67 | if ((ret & ERR_MASK)) { 68 | return ret; 69 | } 70 | 71 | ret = TPM_Transmit(&tpmdata,"Startup"); 72 | 73 | if (ret == 0 && tpmdata.used != 10) { 74 | ret = ERR_BAD_RESP; 75 | } 76 | 77 | return ret; 78 | } 79 | 80 | uint32_t TPM_SaveState() 81 | { 82 | uint32_t ret; 83 | uint32_t ordinal_no = htonl(TPM_ORD_SaveState); 84 | STACK_TPM_BUFFER(tpmdata) 85 | 86 | ret = TSS_buildbuff("00 c1 T l",&tpmdata, 87 | ordinal_no); 88 | if ((ret & ERR_MASK)) { 89 | return ret; 90 | } 91 | 92 | ret = TPM_Transmit(&tpmdata,"SaveState"); 93 | 94 | if (ret == 0 && tpmdata.used != 10) { 95 | ret = ERR_BAD_RESP; 96 | } 97 | 98 | return ret; 99 | } 100 | 101 | uint32_t TPM_Init() 102 | { 103 | uint32_t ret; 104 | uint32_t ordinal_no = htonl(TPM_ORD_Init); 105 | STACK_TPM_BUFFER(tpmdata); 106 | 107 | ret = TSS_buildbuff("00 c1 T l",&tpmdata, 108 | ordinal_no); 109 | if ((ret & ERR_MASK)) { 110 | return ret; 111 | } 112 | 113 | ret = TPM_Transmit(&tpmdata,"Init"); 114 | 115 | return ret; 116 | } 117 | -------------------------------------------------------------------------------- /libtpm/testing.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Testing Routines */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: testing.c 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #include 41 | #include 42 | #include 43 | #ifdef TPM_POSIX 44 | #include 45 | #endif 46 | #ifdef TPM_WINDOWS 47 | #include 48 | #endif 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | uint32_t TPM_SelfTestFull() 58 | { 59 | uint32_t ret; 60 | uint32_t ordinal_no = htonl(TPM_ORD_SelfTestFull); 61 | STACK_TPM_BUFFER(tpmdata) 62 | 63 | ret = TSS_buildbuff("00 c1 T l",&tpmdata, 64 | ordinal_no); 65 | if ((ret & ERR_MASK)) { 66 | return ret; 67 | } 68 | 69 | ret = TPM_Transmit(&tpmdata,"SelfTestFull"); 70 | 71 | if (tpmdata.used != 10) { 72 | ret = ERR_BAD_RESP; 73 | } 74 | 75 | return ret; 76 | } 77 | 78 | uint32_t TPM_ContinueSelfTest() 79 | { 80 | uint32_t ret; 81 | uint32_t ordinal_no = htonl(TPM_ORD_ContinueSelfTest); 82 | STACK_TPM_BUFFER(tpmdata) 83 | 84 | ret = TSS_buildbuff("00 c1 T l",&tpmdata, 85 | ordinal_no); 86 | if ((ret & ERR_MASK)) { 87 | return ret; 88 | } 89 | 90 | ret = TPM_Transmit(&tpmdata,"ContinueSelfTest"); 91 | 92 | if (tpmdata.used != 10) { 93 | ret = ERR_BAD_RESP; 94 | } 95 | 96 | return ret; 97 | } 98 | 99 | 100 | uint32_t TPM_GetTestResult(char * buffer, uint32_t * bufferlen) 101 | { 102 | uint32_t ret; 103 | uint32_t ordinal_no = htonl(TPM_ORD_GetTestResult); 104 | STACK_TPM_BUFFER(tpmdata) 105 | uint32_t len; 106 | 107 | ret = TSS_buildbuff("00 c1 T l",&tpmdata, 108 | ordinal_no); 109 | if ((ret & ERR_MASK)) { 110 | return ret; 111 | } 112 | 113 | ret = TPM_Transmit(&tpmdata,"GetTestResult"); 114 | 115 | if (0 != ret) { 116 | return ret; 117 | } 118 | 119 | ret = tpm_buffer_load32(&tpmdata, TPM_DATA_OFFSET, &len); 120 | if ((ret & ERR_MASK)) { 121 | return ret; 122 | } 123 | 124 | if (tpmdata.used != 10+4+len) { 125 | ret = ERR_BAD_RESP; 126 | } 127 | 128 | if (buffer && ret == 0) { 129 | *bufferlen = MIN(len, *bufferlen); 130 | memcpy(buffer, 131 | &tpmdata.buffer[TPM_DATA_OFFSET+TPM_U32_SIZE], 132 | *bufferlen); 133 | } 134 | 135 | return ret; 136 | } 137 | 138 | uint32_t TPM_CertifySelfTest(uint32_t keyhandle, 139 | unsigned char *usageAuth, // HMAC key 140 | unsigned char *antiReplay, 141 | struct tpm_buffer *signature 142 | ) 143 | { 144 | STACK_TPM_BUFFER(tpmdata) 145 | uint32_t ordinal_no = htonl(TPM_ORD_CertifySelfTest); 146 | uint32_t ret; 147 | uint32_t keyhandle_no = htonl(keyhandle); 148 | uint32_t _sigSize; 149 | 150 | ret = needKeysRoom(keyhandle, 0, 0, 0); 151 | if (ret != 0) { 152 | return ret; 153 | } 154 | /* check input arguments */ 155 | 156 | if (NULL != usageAuth) { 157 | unsigned char nonceodd[TPM_NONCE_SIZE]; 158 | unsigned char authdata[TPM_NONCE_SIZE]; 159 | TPM_BOOL c = 0; 160 | session sess; 161 | 162 | /* Open OSAP Session */ 163 | ret = TSS_SessionOpen(SESSION_DSAP | SESSION_OSAP | SESSION_OIAP, 164 | &sess, 165 | usageAuth, TPM_ET_KEYHANDLE, keyhandle); 166 | 167 | if (ret != 0) return ret; 168 | 169 | /* generate odd nonce */ 170 | ret = TSS_gennonce(nonceodd); 171 | if (0 == ret) return ERR_CRYPT_ERR; 172 | 173 | /* move Network byte order data to variable for hmac calculation */ 174 | ret = TSS_authhmac(authdata,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE,TSS_Session_GetENonce(&sess),nonceodd,c, 175 | TPM_U32_SIZE,&ordinal_no, 176 | TPM_HASH_SIZE,antiReplay, 177 | 0,0); 178 | 179 | if (0 != ret) { 180 | TSS_SessionClose(&sess); 181 | return ret; 182 | } 183 | /* build the request buffer */ 184 | ret = TSS_buildbuff("00 c2 T l l % L % o %", &tpmdata, 185 | ordinal_no, 186 | keyhandle_no, 187 | TPM_HASH_SIZE, antiReplay, 188 | TSS_Session_GetHandle(&sess), 189 | TPM_HASH_SIZE, nonceodd, 190 | c, 191 | TPM_HASH_SIZE,authdata); 192 | 193 | if ((ret & ERR_MASK) != 0) { 194 | TSS_SessionClose(&sess); 195 | return ret; 196 | } 197 | 198 | /* transmit the request buffer to the TPM device and read the reply */ 199 | ret = TPM_Transmit(&tpmdata,"CertifySelfTest - AUTH1"); 200 | TSS_SessionClose(&sess); 201 | 202 | if (ret != 0) { 203 | return ret; 204 | } 205 | /* check the HMAC in the response */ 206 | 207 | ret = tpm_buffer_load32(&tpmdata,TPM_DATA_OFFSET, &_sigSize); 208 | if ((ret & ERR_MASK)) { 209 | return ret; 210 | } 211 | 212 | ret = TSS_checkhmac1(&tpmdata,ordinal_no,nonceodd,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE, 213 | TPM_U32_SIZE+_sigSize, TPM_DATA_OFFSET, 214 | 0,0); 215 | if (0 != ret) { 216 | return ret; 217 | } 218 | } else { 219 | ret = TSS_buildbuff("00 c1 T l l %", &tpmdata, 220 | ordinal_no, 221 | keyhandle_no, 222 | TPM_HASH_SIZE, antiReplay); 223 | if ((ret & ERR_MASK) != 0) { 224 | return ret; 225 | } 226 | 227 | /* transmit the request buffer to the TPM device and read the reply */ 228 | ret = TPM_Transmit(&tpmdata,"CertifySelfTest"); 229 | if (0 != ret ) { 230 | return ret; 231 | } 232 | 233 | ret = tpm_buffer_load32(&tpmdata,TPM_DATA_OFFSET, &_sigSize); 234 | if ((ret & ERR_MASK)) { 235 | return ret; 236 | } 237 | } 238 | 239 | if (NULL != signature) { 240 | SET_TPM_BUFFER(signature, 241 | &tpmdata.buffer[TPM_DATA_OFFSET+TPM_U32_SIZE], 242 | _sigSize); 243 | } 244 | 245 | return ret; 246 | } 247 | -------------------------------------------------------------------------------- /libtpm/ticks.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Tick Routines */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: ticks.c 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #include 41 | #include 42 | #include 43 | #ifdef TPM_POSIX 44 | #include 45 | #endif 46 | #ifdef TPM_WINDOWS 47 | #include 48 | #endif 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | 58 | /****************************************************************************/ 59 | /* */ 60 | /* */ 61 | /* The arguments are... */ 62 | /* */ 63 | /* */ 64 | 65 | uint32_t TPM_GetTicks(unsigned char * tickbuffer) 66 | { 67 | uint32_t ret; 68 | uint32_t ordinal_no = htonl(TPM_ORD_GetTicks); 69 | STACK_TPM_BUFFER(tpmdata) 70 | 71 | ret = TSS_buildbuff("00 c1 T l",&tpmdata, 72 | ordinal_no); 73 | if ((ret & ERR_MASK)) { 74 | return ret; 75 | } 76 | 77 | ret = TPM_Transmit(&tpmdata,"GetTicks"); 78 | 79 | if (0 != ret) 80 | return ret; 81 | 82 | memcpy(tickbuffer, 83 | &tpmdata.buffer[TPM_DATA_OFFSET], 84 | sizeof(TPM_CURRENT_TICKS)-2*TPM_U32_SIZE); 85 | 86 | return ret; 87 | } 88 | 89 | 90 | /****************************************************************************/ 91 | /* */ 92 | /*Apply a timestamp to a passed blob */ 93 | /* */ 94 | /* The arguments are... */ 95 | /* */ 96 | /* keyhandle is the handle of the key used to seal the data */ 97 | /* 0x40000000 for the SRK */ 98 | /* usageauth The sha'ed usage password */ 99 | /* tickbuff A pointer to an area that will hold the current ticks of the */ 100 | /* TPM upon return; may be NULL */ 101 | /* sigbuf a pointer to an area containing the signature upon returns */ 102 | /* sifbuflen an integer that indicates the size of the sigbuf on input and */ 103 | /* the size of the valid data in sigbuf upon return */ 104 | /****************************************************************************/ 105 | uint32_t TPM_TickStampBlob(uint32_t keyhandle, 106 | unsigned char * digestToStamp, 107 | unsigned char * usageauth, 108 | unsigned char * antireplay, 109 | unsigned char * tickbuff, 110 | struct tpm_buffer *signature) 111 | { 112 | STACK_TPM_BUFFER( tpmdata ) 113 | unsigned char nonceodd[TPM_NONCE_SIZE]; 114 | unsigned char authdata[TPM_NONCE_SIZE]; 115 | unsigned char c = 0; 116 | uint32_t ordinal_no = htonl(TPM_ORD_TickStampBlob); 117 | uint32_t ret; 118 | uint32_t keyhandle_no = htonl(keyhandle); 119 | uint32_t len; 120 | 121 | ret = needKeysRoom(keyhandle, 0, 0, 0); 122 | if (ret != 0) { 123 | return ret; 124 | } 125 | 126 | if (NULL != usageauth) { 127 | uint32_t size; 128 | session sess; 129 | 130 | TSS_gennonce(nonceodd); 131 | 132 | ret = TSS_SessionOpen(SESSION_OSAP|SESSION_OIAP, 133 | &sess, 134 | usageauth, TPM_ET_KEYHANDLE, keyhandle); 135 | 136 | if (0 != ret) { 137 | return ret; 138 | } 139 | 140 | ret = TSS_authhmac(authdata,/*usageauth*/TSS_Session_GetAuth(&sess),TPM_HASH_SIZE,TSS_Session_GetENonce(&sess),nonceodd,c, 141 | TPM_U32_SIZE, &ordinal_no, 142 | TPM_HASH_SIZE, antireplay, 143 | TPM_HASH_SIZE, digestToStamp, 144 | 0,0); 145 | 146 | if (0 != ret) { 147 | TSS_SessionClose(&sess); 148 | return ret; 149 | } 150 | 151 | /* build the request buffer */ 152 | ret = TSS_buildbuff("00 c2 T l l % % L % o %", &tpmdata, 153 | ordinal_no, 154 | keyhandle_no, 155 | TPM_HASH_SIZE, antireplay, 156 | TPM_HASH_SIZE, digestToStamp, 157 | TSS_Session_GetHandle(&sess), 158 | TPM_NONCE_SIZE,nonceodd, 159 | c, 160 | TPM_HASH_SIZE,authdata); 161 | 162 | if ((ret & ERR_MASK)) { 163 | return ret; 164 | } 165 | 166 | ret = TPM_Transmit(&tpmdata,"TickStampBlob - AUTH1"); 167 | 168 | TSS_SessionClose(&sess); 169 | 170 | if (0 != ret) { 171 | return ret; 172 | } 173 | 174 | ret = tpm_buffer_load32(&tpmdata, 175 | TPM_DATA_OFFSET + TPM_CURRENT_TICKS_SIZE, 176 | &size); 177 | if ((ret & ERR_MASK)) { 178 | return ret; 179 | } 180 | 181 | ret = TSS_checkhmac1(&tpmdata,ordinal_no,nonceodd,TSS_Session_GetAuth(&sess),TPM_HASH_SIZE, 182 | TPM_CURRENT_TICKS_SIZE+TPM_U32_SIZE+size, TPM_DATA_OFFSET, 183 | 0,0); 184 | if (0 != ret) { 185 | return ret; 186 | } 187 | 188 | if (NULL != tickbuff) { 189 | memcpy(tickbuff, 190 | &tpmdata.buffer[TPM_DATA_OFFSET], 191 | TPM_CURRENT_TICKS_SIZE); 192 | } 193 | if (NULL != signature) { 194 | ret = tpm_buffer_load32(&tpmdata, 195 | TPM_DATA_OFFSET+TPM_CURRENT_TICKS_SIZE, 196 | &len); 197 | if ((ret & ERR_MASK)) { 198 | return ret; 199 | } 200 | SET_TPM_BUFFER(signature, 201 | &tpmdata.buffer[TPM_DATA_OFFSET+TPM_CURRENT_TICKS_SIZE+TPM_U32_SIZE], 202 | len); 203 | } 204 | 205 | } else { 206 | ret = TSS_buildbuff("00 c1 T l l % %",&tpmdata, 207 | ordinal_no, 208 | keyhandle_no, 209 | TPM_HASH_SIZE, antireplay, 210 | TPM_HASH_SIZE, digestToStamp); 211 | if ((ret & ERR_MASK)) { 212 | return ret; 213 | } 214 | 215 | ret = TPM_Transmit(&tpmdata, "TickStampBlob" ); 216 | 217 | if (0 != ret) { 218 | return ret; 219 | } 220 | 221 | if (NULL != tickbuff) { 222 | memcpy(tickbuff, 223 | &tpmdata.buffer[TPM_DATA_OFFSET], 224 | TPM_CURRENT_TICKS_SIZE); 225 | } 226 | if (NULL != signature) { 227 | ret = tpm_buffer_load32(&tpmdata, 228 | TPM_DATA_OFFSET+TPM_CURRENT_TICKS_SIZE, 229 | &len); 230 | if ((ret & ERR_MASK)) { 231 | return ret; 232 | } 233 | SET_TPM_BUFFER(signature, 234 | &tpmdata.buffer[TPM_DATA_OFFSET+TPM_CURRENT_TICKS_SIZE+TPM_U32_SIZE], 235 | len); 236 | } 237 | } 238 | return ret; 239 | } 240 | 241 | -------------------------------------------------------------------------------- /libtpm/tpm.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Utilities */ 4 | /* Written by J. Kravitz */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: tpm.h 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #ifndef TPM_H 41 | #define TPM_H 42 | 43 | #include 44 | #include 45 | #ifdef TPM_POSIX 46 | #include 47 | #endif 48 | #ifdef TPM_WINDOWS 49 | #include 50 | #endif 51 | 52 | #define ERR_MASK 0x80000000 /* mask to define error state */ 53 | /* keep 0x8001000 unassigned since the bash only sees the lowest byte! */ 54 | #define ERR_DUMMY 0x80001000 55 | #define ERR_HMAC_FAIL 0x80001001 /* HMAC authorization verification failed */ 56 | #define ERR_NULL_ARG 0x80001002 /* An argument was NULL that shouldn't be */ 57 | #define ERR_BAD_ARG 0x80001003 /* An argument had an invalid value */ 58 | #define ERR_CRYPT_ERR 0x80001004 /* An error occurred in an OpenSSL library call */ 59 | #define ERR_IO 0x80001005 /* An I/O Error occurred */ 60 | #define ERR_MEM_ERR 0x80001006 /* A memory allocation error occurred */ 61 | #define ERR_BAD_FILE 0x80001007 /* File error occurred */ 62 | #define ERR_BAD_DATA 0x80001008 /* data read from a stream were bad */ 63 | #define ERR_BAD_SIZE 0x80001009 /* the size of the data to send to the TPM is too large */ 64 | #define ERR_BUFFER 0x8000100a /* the size of the buffer is too small */ 65 | #define ERR_STRUCTURE 0x8000100b /* this is not the stream for the structure to be parsed */ 66 | #define ERR_NOT_FOUND 0x8000100c /* searched item could not be found */ 67 | #define ERR_ENV_VARIABLE 0x8000100d /* environment variable is not set */ 68 | #define ERR_NO_TRANSPORT 0x8000100e /* no transport allowed for this ordinal */ 69 | #define ERR_BADRESPONSETAG 0x8000100f /* bad response tag in message */ 70 | #define ERR_SIGNATURE 0x80001010 /* bad signature */ 71 | #define ERR_PCR_LIST_NOT_IMA 0x80001011 /* PCR values do not correspond to that in IMA */ 72 | #define ERR_CHECKSUM 0x80001012 /* Checksum not correct */ 73 | #define ERR_BAD_RESP 0x80001013 /* response from TPM not formatted correctly */ 74 | #define ERR_BAD_SESSION_TYPE 0x80001014 /* session type choice is not good */ 75 | #define ERR_BAD_FILE_CLOSE 0x80001015 /* close() or fclose() failed */ 76 | #define ERR_BAD_FILE_WRITE 0x80001016 /* write() failed */ 77 | #define ERR_BAD_FILE_READ 0x80001017 /* read() failed */ 78 | 79 | #define ERR_LAST 0x80001018 /* keep this as the last error code !!!! */ 80 | 81 | #define TPM_MAX_BUFF_SIZE 4096 82 | #define TPM_HASH_SIZE 20 83 | #define TPM_NONCE_SIZE 20 84 | 85 | #define TPM_U16_SIZE 2 86 | #define TPM_U32_SIZE 4 87 | 88 | #define TPM_PARAMSIZE_OFFSET TPM_U16_SIZE 89 | #define TPM_RETURN_OFFSET ( TPM_U16_SIZE + TPM_U32_SIZE ) 90 | #define TPM_DATA_OFFSET ( TPM_RETURN_OFFSET + TPM_U32_SIZE ) 91 | 92 | 93 | static inline void store32(unsigned char *const buffer, 94 | int offset, 95 | uint32_t value) 96 | { 97 | int i; 98 | for (i = 3; i >= 0; i--) { 99 | buffer[offset+i] = (value & 0xff); 100 | value >>= 8; 101 | } 102 | } 103 | 104 | 105 | static inline void store16(unsigned char *const buffer, 106 | int offset, 107 | uint16_t value) 108 | { 109 | int i; 110 | for (i = 1; i >= 0; i--) { 111 | buffer[offset+i] = (value & 0xff); 112 | value >>= 8; 113 | } 114 | } 115 | 116 | #define STORE32(buffer,offset,value) store32(buffer, offset, value) 117 | #define STORE16(buffer,offset,value) store16(buffer, offset, value) 118 | #if __BYTE_ORDER == __LITTLE_ENDIAN 119 | # define STORE32N(buffer,offset,value) memcpy(&buffer[offset], &value, 4); 120 | # define STORE16N(buffer,offset,value) memcpy(&buffer[offset], &value, 2); 121 | #elif __BYTE_ORDER == __BIG_ENDIAN 122 | # define STORE32N(buffer,offset,value) STORE32(buffer, offset, value) 123 | # define STORE16N(buffer,offset,value) STORE16(buffer, offset, value) 124 | #else 125 | # error __BYTE_ORDER not defined 126 | #endif 127 | #define LOAD32(buffer,offset) load32(buffer, offset) 128 | #define LOAD16(buffer,offset) load16(buffer, offset) 129 | #define LOAD32N(buffer,offset) load32N(buffer, offset) 130 | #define LOAD16N(buffer,offset) load16N(buffer, offset) 131 | 132 | static inline uint32_t load32(const unsigned char *buffer, int offset) 133 | { 134 | int i; 135 | uint32_t res = 0; 136 | 137 | for (i = 0; i <= 3; i++) { 138 | res <<= 8; 139 | res |= buffer[offset+i]; 140 | } 141 | return res; 142 | } 143 | 144 | 145 | static inline uint16_t load16(const unsigned char *buffer, int offset) 146 | { 147 | int i; 148 | uint16_t res = 0; 149 | 150 | for (i = 0; i <= 1; i++) { 151 | res <<= 8; 152 | res |= buffer[offset+i]; 153 | } 154 | return res; 155 | } 156 | 157 | 158 | static inline uint32_t load32N(const unsigned char *buffer, int offset) 159 | { 160 | uint32_t res; 161 | memcpy(&res, &buffer[offset], sizeof(res)); 162 | return res; 163 | } 164 | 165 | static inline uint16_t load16N(const unsigned char *buffer, int offset) 166 | { 167 | uint16_t res; 168 | memcpy(&res, &buffer[offset], sizeof(res)); 169 | return res; 170 | } 171 | 172 | #define TPM_CURRENT_TICKS_SIZE (sizeof(TPM_STRUCTURE_TAG)+2*TPM_U32_SIZE+TPM_U16_SIZE+TPM_NONCE_SIZE) 173 | 174 | struct tpm_buffer 175 | { 176 | uint32_t size; 177 | uint32_t used; 178 | uint32_t flags; 179 | unsigned char buffer[TPM_MAX_BUFF_SIZE]; 180 | }; 181 | 182 | enum { 183 | BUFFER_FLAG_ON_STACK = 1, 184 | }; 185 | 186 | #define STACK_TPM_BUFFER(X) \ 187 | struct tpm_buffer X = { \ 188 | .size = sizeof( X.buffer ), \ 189 | .used = 0, \ 190 | .flags = BUFFER_FLAG_ON_STACK, \ 191 | .buffer = ""}; 192 | #define RESET_TPM_BUFFER(X) \ 193 | (X)->used = 0 194 | #define ALLOC_TPM_BUFFER(X,S) \ 195 | struct tpm_buffer *X = TSS_AllocTPMBuffer(S); 196 | #define FREE_TPM_BUFFER(X) \ 197 | TSS_FreeTPMBuffer(X) 198 | #define SET_TPM_BUFFER(X, src, len) \ 199 | do { \ 200 | uint32_t to_copy = (X)->size > len ? len : (X)->size; \ 201 | memcpy((X)->buffer, src, to_copy); \ 202 | (X)->used = to_copy; \ 203 | } while (0); 204 | #define IS_TPM_BUFFER_EMPTY(X) \ 205 | ((X)->used == 0) 206 | 207 | struct tpm_buffer *TSS_AllocTPMBuffer(int len); 208 | 209 | static inline struct tpm_buffer *clone_tpm_buffer(struct tpm_buffer *orig) { 210 | struct tpm_buffer * buf = TSS_AllocTPMBuffer(orig->used + 20); 211 | if (buf) { 212 | SET_TPM_BUFFER(buf, orig->buffer, orig->used); 213 | } 214 | return buf; 215 | } 216 | 217 | #if defined (__x86_64__) 218 | #define OUT_FORMAT(a,b) b 219 | #else 220 | #define OUT_FORMAT(a,b) a 221 | #endif 222 | 223 | #endif 224 | -------------------------------------------------------------------------------- /libtpm/tpm_lowlevel.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Low Level Transport */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: tpm_lowlevel.h 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #ifndef TPM_LOWLEVEL_H 41 | #define TPM_LOWLEVEL_H 42 | 43 | #include "tpm.h" 44 | 45 | struct tpm_transport 46 | { 47 | uint32_t (*open)(int *fd); 48 | uint32_t (*close)(int fd); 49 | uint32_t (*send)(int fd, struct tpm_buffer *tb, const char *msg); 50 | uint32_t (*recv)(int fd, struct tpm_buffer *tb); 51 | }; 52 | 53 | enum { 54 | TPM_LOWLEVEL_TRANSPORT_CHARDEV = 1, 55 | TPM_LOWLEVEL_TRANSPORT_TCP_SOCKET, 56 | TPM_LOWLEVEL_TRANSPORT_UNIXIO, 57 | TPM_LOWLEVEL_TRANSPORT_CCA, 58 | TPM_LOWLEVEL_TRANSPORT_LIBTPMS, 59 | }; 60 | 61 | void TPM_LowLevel_TransportSocket_Set(void); 62 | void TPM_LowLevel_TransportUnixIO_Set(void); 63 | void TPM_LowLevel_TransportCharDev_Set(void); 64 | #ifdef TPM_USE_LIBTPMS 65 | void TPM_LowLevel_TransportLibTPMS_Set(void); 66 | #endif 67 | struct tpm_transport *TPM_LowLevel_Transport_Set(struct tpm_transport *new_tp); 68 | int TPM_LowLevel_Transport_Init(int choice); 69 | int TPM_LowLevel_Use_VTPM(void); 70 | int TPM_LowLevel_VTPM_Set(int state); 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /libtpm/tpm_types.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Types */ 4 | /* Written by Ken Goldman */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: tpm_types.h 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #ifndef TPM_TYPES_H 41 | #define TPM_TYPES_H 42 | 43 | #include 44 | 45 | #ifdef TPM_WINDOWS 46 | #include 47 | #endif 48 | #if defined (TPM_POSIX) || defined (TPM_SYSTEM_P) 49 | #include /* for byte order conversions */ 50 | #endif 51 | 52 | /* 2.2.1 Basic data types rev 87 */ 53 | typedef unsigned char BYTE; /* Basic byte used to transmit all character fields. */ 54 | typedef unsigned char TPM_BOOL; /* TRUE/FALSE field. TRUE = 0x01, FALSE = 0x00 Use TPM_BOOL 55 | because MS VC++ defines BOOL on Windows */ 56 | 57 | /* 2.2.2 Boolean types rev 107 */ 58 | 59 | #undef TRUE 60 | #define TRUE 0x01 /* Assertion */ 61 | #undef FALSE 62 | #define FALSE 0x00 /* Contradiction */ 63 | 64 | /* 2.2.3 Helper redefinitions rev 101 65 | 66 | The following definitions are to make the definitions more explicit and easier to read. 67 | 68 | NOTE: They cannot be changed without breaking the serialization. 69 | */ 70 | 71 | typedef BYTE TPM_AUTH_DATA_USAGE; /* Indicates the conditions where it is required that 72 | authorization be presented. */ 73 | typedef BYTE TPM_PAYLOAD_TYPE; /* The information as to what the payload is in an encrypted 74 | structure */ 75 | typedef BYTE TPM_VERSION_BYTE; /* The version info breakdown */ 76 | typedef BYTE TPM_DA_STATE; /* The state of the dictionary attack mitigation logic */ 77 | 78 | /* added kgold */ 79 | typedef BYTE TPM_ENT_TYPE; /* LSB of TPM_ENTITY_TYPE */ 80 | typedef BYTE TPM_ADIP_ENC_SCHEME; /* MSB of TPM_ENTITY_TYPE */ 81 | 82 | typedef uint16_t TPM_PROTOCOL_ID; /* The protocol in use. */ 83 | typedef uint16_t TPM_STARTUP_TYPE; /* Indicates the start state. */ 84 | typedef uint16_t TPM_ENC_SCHEME; /* The definition of the encryption scheme. */ 85 | typedef uint16_t TPM_SIG_SCHEME; /* The definition of the signature scheme. */ 86 | typedef uint16_t TPM_MIGRATE_SCHEME; /* The definition of the migration scheme */ 87 | typedef uint16_t TPM_PHYSICAL_PRESENCE; /* Sets the state of the physical presence mechanism. */ 88 | typedef uint16_t TPM_ENTITY_TYPE; /* Indicates the types of entity that are supported by the 89 | TPM. */ 90 | typedef uint16_t TPM_KEY_USAGE; /* Indicates the permitted usage of the key. */ 91 | typedef uint16_t TPM_EK_TYPE; /* The type of asymmetric encrypted structure in use by the 92 | endorsement key */ 93 | typedef uint16_t TPM_STRUCTURE_TAG; /* The tag for the structure */ 94 | typedef uint16_t TPM_PLATFORM_SPECIFIC; /* The platform specific spec to which the information 95 | relates to */ 96 | typedef uint32_t TPM_COMMAND_CODE; /* The command ordinal. */ 97 | typedef uint32_t TPM_CAPABILITY_AREA; /* Identifies a TPM capability area. */ 98 | typedef uint32_t TPM_KEY_FLAGS; /* Indicates information regarding a key. */ 99 | typedef uint32_t TPM_ALGORITHM_ID; /* Indicates the type of algorithm. */ 100 | typedef uint32_t TPM_MODIFIER_INDICATOR; /* The locality modifier */ 101 | typedef uint32_t TPM_ACTUAL_COUNT; /* The actual number of a counter. */ 102 | typedef uint32_t TPM_TRANSPORT_ATTRIBUTES; /* Attributes that define what options are in use 103 | for a transport session */ 104 | typedef uint32_t TPM_AUTHHANDLE; /* Handle to an authorization session */ 105 | typedef uint32_t TPM_DIRINDEX; /* Index to a DIR register */ 106 | typedef uint32_t TPM_KEY_HANDLE; /* The area where a key is held assigned by the TPM. */ 107 | typedef uint32_t TPM_PCRINDEX; /* Index to a PCR register */ 108 | typedef uint32_t TPM_RESULT; /* The return code from a function */ 109 | typedef uint32_t TPM_RESOURCE_TYPE; /* The types of resources that a TPM may have using internal 110 | resources */ 111 | typedef uint32_t TPM_KEY_CONTROL; /* Allows for controlling of the key when loaded and how to 112 | handle TPM_Startup issues */ 113 | typedef uint32_t TPM_NV_INDEX; /* The index into the NV storage area */ 114 | typedef uint32_t TPM_FAMILY_ID; /* The family ID. Families ID's are automatically assigned a 115 | sequence number by the TPM. A trusted process can set the 116 | FamilyID value in an individual row to zero, which 117 | invalidates that row. The family ID resets to zero on 118 | each change of TPM Owner. */ 119 | typedef uint32_t TPM_FAMILY_VERIFICATION; /* A value used as a label for the most recent 120 | verification of this family. Set to zero when not 121 | in use. */ 122 | typedef uint32_t TPM_STARTUP_EFFECTS; /* How the TPM handles var */ 123 | typedef uint32_t TPM_SYM_MODE; /* The mode of a symmetric encryption */ 124 | typedef uint32_t TPM_FAMILY_FLAGS; /* The family flags */ 125 | typedef uint32_t TPM_DELEGATE_INDEX; /* The index value for the delegate NV table */ 126 | typedef uint32_t TPM_CMK_DELEGATE; /* The restrictions placed on delegation of CMK 127 | commands */ 128 | typedef uint32_t TPM_COUNT_ID; /* The ID value of a monotonic counter */ 129 | typedef uint32_t TPM_REDIT_COMMAND; /* A command to execute */ 130 | typedef uint32_t TPM_TRANSHANDLE; /* A transport session handle */ 131 | typedef uint32_t TPM_HANDLE; /* A generic handle could be key, transport etc. */ 132 | typedef uint32_t TPM_FAMILY_OPERATION; /* What operation is happening */ 133 | 134 | /* Not in specification */ 135 | 136 | typedef uint16_t TPM_TAG; /* The command and response tags */ 137 | 138 | typedef unsigned char * TPM_SYMMETRIC_KEY_TOKEN; /* abstract symmetric key token */ 139 | typedef unsigned char * TPM_BIGNUM; /* abstract bignum */ 140 | 141 | #endif 142 | -------------------------------------------------------------------------------- /libtpm/tpmkeys.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Key Structures */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: tpmkeys.h 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #ifndef TPMKEYS_H 41 | #define TPMKEYS_H 42 | #include "tpm.h" 43 | #include "tpm_structures.h" 44 | #include 45 | 46 | #ifndef TPM_MAXIMUM_KEY_SIZE 47 | #define TPM_MAXIMUM_KEY_SIZE 4096 48 | #endif 49 | 50 | 51 | #define TPM_SIZED_BUFFER_EMB(SIZE_OF_BUFFER,uniq,name) \ 52 | struct uniq { \ 53 | uint32_t size; \ 54 | BYTE buffer[SIZE_OF_BUFFER]; \ 55 | } name 56 | 57 | 58 | typedef struct tdTPM_RSA_KEY_PARMS_EMB { 59 | uint32_t keyLength; 60 | uint32_t numPrimes; 61 | uint32_t exponentSize; 62 | BYTE exponent[3]; 63 | } TPM_RSA_KEY_PARMS_EMB; 64 | 65 | 66 | typedef struct tdTPM_SYMMETRIC_KEY_PARMS_EMB { 67 | uint32_t keyLength; 68 | uint32_t blockSize; 69 | uint32_t ivSize; 70 | BYTE IV[256]; 71 | } TPM_SYMMETRIC_KEY_PARMS_EMB; 72 | 73 | typedef struct tdTPM_KEY_PARMS_EMB { 74 | TPM_ALGORITHM_ID algorithmID; /* This SHALL be the key algorithm in use */ 75 | TPM_ENC_SCHEME encScheme; /* This SHALL be the encryption scheme that the key uses to encrypt 76 | information */ 77 | TPM_SIG_SCHEME sigScheme; /* This SHALL be the signature scheme that the key uses to perform 78 | digital signatures */ 79 | union { 80 | TPM_RSA_KEY_PARMS_EMB rsaKeyParms; 81 | TPM_SYMMETRIC_KEY_PARMS_EMB symKeyParms; 82 | } u; 83 | } TPM_KEY_PARMS_EMB; 84 | 85 | 86 | typedef struct tdTPM_STORE_PUBKEY_EMB { 87 | uint32_t keyLength; 88 | BYTE modulus[TPM_MAXIMUM_KEY_SIZE/8]; 89 | } TPM_STORE_PUBKEY_EMB; 90 | 91 | 92 | typedef struct tdTPM_KEY_EMB { 93 | TPM_STRUCT_VER ver; 94 | TPM_KEY_USAGE keyUsage; 95 | TPM_KEY_FLAGS keyFlags; 96 | TPM_AUTH_DATA_USAGE authDataUsage; 97 | TPM_KEY_PARMS_EMB algorithmParms; 98 | TPM_SIZED_BUFFER_EMB(256, 99 | pcrInfo_TPM_KEY_EMB, pcrInfo); 100 | TPM_STORE_PUBKEY_EMB pubKey; 101 | TPM_SIZED_BUFFER_EMB(1024, encData_TPM_KEY_EMB, encData); 102 | } TPM_KEY_EMB; 103 | 104 | 105 | typedef struct tdTPM_KEY12_EMB { 106 | TPM_STRUCTURE_TAG tag; 107 | uint16_t fill; 108 | TPM_KEY_USAGE keyUsage; 109 | TPM_KEY_FLAGS keyFlags; 110 | TPM_AUTH_DATA_USAGE authDataUsage; 111 | TPM_KEY_PARMS_EMB algorithmParms; 112 | TPM_SIZED_BUFFER_EMB(256, 113 | pcrInfo_TPM_KEY12_EMB, pcrInfo); 114 | TPM_STORE_PUBKEY_EMB pubKey; 115 | TPM_SIZED_BUFFER_EMB(1024, encData_TPM_KEY12_EMB, encData); 116 | } TPM_KEY12_EMB; 117 | 118 | typedef struct pubkeydata 119 | { 120 | TPM_KEY_PARMS_EMB algorithmParms; 121 | TPM_STORE_PUBKEY_EMB pubKey; 122 | TPM_SIZED_BUFFER_EMB(256, 123 | pcrInfo_pubkeydata, pcrInfo); 124 | } pubkeydata; 125 | 126 | typedef struct keydata 127 | { 128 | union { 129 | TPM_STRUCT_VER ver; 130 | TPM_STRUCTURE_TAG tag; // 1 131 | } v; 132 | TPM_KEY_USAGE keyUsage; // 2 133 | TPM_KEY_FLAGS keyFlags; // 3 134 | TPM_AUTH_DATA_USAGE authDataUsage; // 4 135 | pubkeydata pub; 136 | TPM_SIZED_BUFFER_EMB(1024, encData_keydata, encData); 137 | } keydata; 138 | 139 | 140 | #endif 141 | -------------------------------------------------------------------------------- /libtpm/tpmutil.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Utilities */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: tpmutil.h 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | #ifndef TPMUTIL_H 41 | #define TPMUTIL_H 42 | 43 | #include 44 | 45 | #include 46 | 47 | #include 48 | 49 | #include 50 | 51 | #ifdef MIN 52 | #undef MIN 53 | #endif 54 | 55 | #define MIN(x,y) (x) < (y) ? (x) : (y) 56 | 57 | #define TPM_COUNTER_VALUE_SIZE 10 58 | 59 | #define TPM_MAX_TRANSPORTS 10 60 | 61 | /* AES requires data lengths that are a multiple of the block size */ 62 | #define TPM_AES_BITS 128 63 | /* The AES block size is always 16 bytes */ 64 | #define TPM_AES_BLOCK_SIZE 16 65 | 66 | 67 | struct tpm_buffer; 68 | 69 | uint32_t TSS_getsize(unsigned char *rsp); 70 | int TSS_gennonce(unsigned char *nonce); 71 | int TSS_buildbuff(char *format,struct tpm_buffer *, ...); 72 | int TSS_parsebuff(char *format,const struct tpm_buffer *, uint32_t offset, ...); 73 | uint32_t TPM_Transmit(struct tpm_buffer *,const char *msg); 74 | uint32_t TPM_Transmit_NoTransport(struct tpm_buffer *,const char *msg); 75 | uint32_t TPM_Send(struct tpm_buffer *,const char *); 76 | int TPM_setlog(int flag); 77 | void TSS_sha1(void *input, unsigned int len, unsigned char *output); 78 | uint32_t TSS_SHAFile(const char *filename, unsigned char *hash); 79 | void showBuff(unsigned char* buff, char* string); 80 | 81 | uint32_t TPM_GetDelegationBlob(uint32_t etype, 82 | uint32_t keyhandle, 83 | unsigned char *passHash, 84 | unsigned char *buffer, uint32_t *bufferSize); 85 | uint32_t TPM_AddDelegationBlob(uint32_t etype, 86 | uint32_t keyhandle, 87 | unsigned char *oldPassHash, 88 | unsigned char *newPassHash, 89 | unsigned char *buffer, uint32_t bufferSize); 90 | uint32_t TPM_ResetDelegation(void); 91 | 92 | 93 | uint32_t _TPM_AuditInputstream(const struct tpm_buffer *req, int is_encrypted); 94 | uint32_t _TPM_AuditOutputstream(const struct tpm_buffer *res, uint32_t ord, 95 | int is_encrypted); 96 | uint32_t _TPM_IsAuditedOrdinal(uint32_t ord, uint32_t *rc); 97 | uint32_t TPM_SetAuditedOrdinal(uint32_t ord); 98 | uint32_t TPM_ClearAuditedOrdinal(uint32_t ord); 99 | uint32_t TPM_SetAuditingCounterValue(TPM_COUNTER_VALUE *cv); 100 | uint32_t TPM_ResetAuditing(void); 101 | 102 | uint32_t getNumHandles(uint32_t ord); 103 | uint32_t getNumRespHandles(uint32_t ord); 104 | #if 0 105 | uint32_t TPM_OpenClientSocket(int *sock_fd); 106 | uint32_t TPM_CloseClientSocket(int sock_fd); 107 | uint32_t TPM_TransmitSocket(int sock_fd, struct tpm_buffer *tb); 108 | uint32_t TPM_ReceiveSocket(int sock_fd, struct tpm_buffer *tb); 109 | uint32_t TPM_ReceiveBytes(int sock_fd, 110 | unsigned char *buffer, 111 | size_t nbytes); 112 | #endif 113 | 114 | uint32_t tpm_buffer_load32 (const struct tpm_buffer *tb, uint32_t offset, uint32_t *val); 115 | uint32_t tpm_buffer_load32N(const struct tpm_buffer *tb, uint32_t offset, uint32_t *val); 116 | uint32_t tpm_buffer_load16 (const struct tpm_buffer *tb, uint32_t offset, uint16_t *val); 117 | uint32_t tpm_buffer_load16N(const struct tpm_buffer *tb, uint32_t offset, uint16_t *val); 118 | uint32_t tpm_buffer_store32(struct tpm_buffer *tb, uint32_t val); 119 | uint32_t tpm_buffer_store(struct tpm_buffer *dest, struct tpm_buffer *src, uint32_t soff, uint32_t slen); 120 | 121 | uint32_t parseHash(char *string, unsigned char *hash); 122 | TPM_RESULT TPM_AES_ctr128_Encrypt(unsigned char *data_out, 123 | const unsigned char *data_in, 124 | unsigned long data_size, 125 | const AES_KEY *aes_enc_key, 126 | unsigned char ctr[TPM_AES_BLOCK_SIZE]); 127 | TPM_RESULT TSS_MGF1(unsigned char *mask, 128 | uint32_t maskLen, 129 | const unsigned char *mgfSeed, 130 | uint32_t mgfSeedlen); 131 | TPM_RESULT TSS_SHA1(TPM_DIGEST md, ...); 132 | 133 | 134 | #if 0 135 | void TPM_XOR(unsigned char *out, 136 | const unsigned char *in1, 137 | const unsigned char *in2, 138 | size_t length); 139 | #endif 140 | 141 | int allowsTransport(uint32_t ord); 142 | 143 | void _TPM_getTransportAlgIdEncScheme(TPM_ALGORITHM_ID *algId, 144 | TPM_ENC_SCHEME *encScheme); 145 | void TPM_DetermineSessionEncryption(const session *, int *); 146 | 147 | uint32_t needKeysRoom(uint32_t key1, uint32_t key2, uint32_t key3, 148 | int room); 149 | uint32_t needKeysRoom_Stacked(uint32_t key1, uint32_t *orig_key1); 150 | uint32_t needKeysRoom_Stacked_Undo(uint32_t swapout_key, uint32_t swapin_key); 151 | 152 | 153 | #endif 154 | -------------------------------------------------------------------------------- /libtpm/tpmutil_libtpms.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM LibTPMS Interface Functions */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: tpmutil_libtpms.c 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* IBM Confidential */ 9 | /* OCO Source Materials */ 10 | /* (c) Copyright IBM Corp. 2010 */ 11 | /* All Rights Reserved */ 12 | /* */ 13 | /* The source code for this program is not published or otherwise */ 14 | /* divested of its trade secrets, irrespective of what has been */ 15 | /* deposited with the U.S. Copyright Office. */ 16 | /* */ 17 | /********************************************************************************/ 18 | 19 | #ifdef TPM_USE_LIBTPMS 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "tpm_types.h" 26 | #include "tpm_error.h" 27 | 28 | #ifdef USE_IN_TREE_LIBTPMS 29 | 30 | #include "../../../src/tpm_library.h" 31 | 32 | #else 33 | 34 | #include 35 | 36 | #endif 37 | 38 | #include "tpmutil.h" 39 | #include "tpm_lowlevel.h" 40 | 41 | 42 | static uint32_t TPM_OpenLibTPMS(int *sockfd); 43 | static uint32_t TPM_CloseLibTPMS(int sockfd); 44 | static uint32_t TPM_SendLibTPMS(int sockfd, struct tpm_buffer *tb, 45 | const char *msg); 46 | static uint32_t TPM_ReceiveLibTPMS(int sockfd, struct tpm_buffer *tb); 47 | 48 | static struct tpm_transport libtpms_transport = { 49 | .open = TPM_OpenLibTPMS, 50 | .close = TPM_CloseLibTPMS, 51 | .send = TPM_SendLibTPMS, 52 | .recv = TPM_ReceiveLibTPMS, 53 | }; 54 | 55 | void TPM_LowLevel_TransportLibTPMS_Set(void) 56 | { 57 | TPM_LowLevel_Transport_Set(&libtpms_transport); 58 | } 59 | 60 | 61 | /* 62 | * Functions that implement the transport 63 | */ 64 | static uint32_t TPM_OpenLibTPMS(int *sockfd) 65 | { 66 | (void)sockfd; 67 | return 0; 68 | } 69 | 70 | static uint32_t TPM_CloseLibTPMS(int sockfd) 71 | { 72 | (void)sockfd; 73 | return 0; 74 | } 75 | 76 | 77 | static uint32_t TPM_SendLibTPMS(int sockfd, struct tpm_buffer *tb, 78 | const char *msg) 79 | { 80 | unsigned char *respbuffer = NULL; 81 | uint32_t resp_size; 82 | uint32_t respbufsize; 83 | uint32_t rc; 84 | char mymsg[1024]; 85 | 86 | (void)sockfd; 87 | 88 | snprintf(mymsg, sizeof(mymsg), "TPM_SendLibTPMS: To TPM [%s]", 89 | msg); 90 | 91 | showBuff(tb->buffer, mymsg); 92 | 93 | rc = TPMLIB_Process(&respbuffer, &resp_size, &respbufsize, 94 | tb->buffer, tb->used); 95 | 96 | if (rc != TPM_SUCCESS) 97 | return ERR_IO; 98 | 99 | if (tb->size < resp_size) 100 | return ERR_BUFFER; 101 | 102 | memcpy(tb->buffer, respbuffer, resp_size); 103 | tb->used = resp_size; 104 | 105 | free(respbuffer); 106 | 107 | snprintf(mymsg, sizeof(mymsg), "TPM_SendLibTPMS: From TPM [%s]", 108 | msg); 109 | 110 | showBuff(tb->buffer, mymsg); 111 | 112 | return 0; 113 | } 114 | 115 | 116 | static uint32_t TPM_ReceiveLibTPMS(int sockfd, struct tpm_buffer *tb) 117 | { 118 | /* 119 | * Doing everything in the transmit function 120 | */ 121 | (void)sockfd; 122 | (void)tb; 123 | return 0; 124 | } 125 | 126 | #endif /* TPM_USE_LIBTPMS */ 127 | 128 | -------------------------------------------------------------------------------- /libtpm/tpmutil_sock.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Socket Communication Functions */ 4 | /* Written by Ken Goldman */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: tpmutil_sock.c 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | 41 | /* These are platform specific. This version uses a TCP/IP socket interface. 42 | 43 | Environment variables are: 44 | 45 | TPM_SERVER_PORT - the client and server socket port number 46 | */ 47 | 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | 54 | #include 55 | 56 | #ifdef TPM_POSIX 57 | #include 58 | #include 59 | #include 60 | #include 61 | #endif 62 | #ifdef TPM_WINDOWS 63 | #include 64 | #endif 65 | #include 66 | #include 67 | 68 | #include 69 | #include 70 | 71 | #include "tpm.h" 72 | #include "tpmfunc.h" 73 | #include "tpm_types.h" 74 | #include "tpm_constants.h" 75 | #include "tpmutil.h" 76 | #include "tpm_lowlevel.h" 77 | 78 | /* local prototypes */ 79 | static uint32_t TPM_OpenClientSocket(int *sock_fd); 80 | static uint32_t TPM_CloseClientSocket(int sock_fd); 81 | static uint32_t TPM_TransmitSocket(int sock_fd, struct tpm_buffer *tb, 82 | const char *msg); 83 | static uint32_t TPM_ReceiveSocket(int sock_fd, struct tpm_buffer *tb); 84 | static uint32_t TPM_ReceiveBytes(int sock_fd, 85 | unsigned char *buffer, 86 | size_t nbytes); 87 | 88 | 89 | /* local variables */ 90 | static struct tpm_transport socket_transport = { 91 | .open = TPM_OpenClientSocket, 92 | .close = TPM_CloseClientSocket, 93 | .send = TPM_TransmitSocket, 94 | .recv = TPM_ReceiveSocket, 95 | }; 96 | 97 | void TPM_LowLevel_TransportSocket_Set(void) 98 | { 99 | TPM_LowLevel_Transport_Set(&socket_transport); 100 | } 101 | 102 | /****************************************************************************/ 103 | /* */ 104 | /* Open the socket to the TPM Host emulation */ 105 | /* */ 106 | /****************************************************************************/ 107 | 108 | /* For Windows, sock_fd is uint */ 109 | 110 | static uint32_t TPM_OpenClientSocket(int *sock_fd) 111 | { 112 | int irc; 113 | #ifdef TPM_WINDOWS 114 | WSADATA wsaData; 115 | #endif 116 | char *port_str; 117 | short port; 118 | struct sockaddr_in serv_addr; 119 | struct hostent *host = NULL; 120 | char *server_name = NULL; 121 | 122 | port_str = getenv("TPM_SERVER_PORT"); 123 | if (port_str == NULL) { 124 | printf("TPM_OpenClientSocket: Error, TPM_SERVER_PORT environment variable not set\n"); 125 | return ERR_IO; 126 | } 127 | irc = sscanf(port_str, "%hu", &port); 128 | if (irc != 1) { 129 | printf("TPM_OpenClientSocket: Error, TPM_SERVER_PORT environment variable invalid\n"); 130 | return ERR_IO; 131 | } 132 | /* get the server host name from the environment variable */ 133 | server_name = getenv("TPM_SERVER_NAME"); 134 | if (server_name == NULL) { /* environment variable not found */ 135 | printf("TPM_OpenClientSocket: TPM_SERVER_NAME environment variable not set\n"); 136 | return ERR_IO; 137 | } 138 | #ifdef TPM_WINDOWS 139 | if ((irc = WSAStartup(0x202, &wsaData)) != 0) { /* if not successful */ 140 | printf("TPM_OpenClientSocket: Error, WSAStartup failed\n"); 141 | WSACleanup(); 142 | return ERR_IO; 143 | } 144 | if ((*sock_fd = socket(AF_INET,SOCK_STREAM, 0)) == INVALID_SOCKET) { 145 | printf("TPM_OpenClientSocket: client socket() error: %u\n", *sock_fd); 146 | return ERR_IO; 147 | } 148 | #endif 149 | #ifdef TPM_POSIX 150 | if ((*sock_fd = socket(AF_INET,SOCK_STREAM, 0)) < 0) { 151 | printf("TPM_OpenClientSocket: client socket error: %d %s\n",errno,strerror(errno)); 152 | return ERR_IO; 153 | } 154 | else { 155 | /* printf("TPM_OpenClientSocket: client socket: success\n"); */ 156 | } 157 | #endif 158 | /* establish the connection to server */ 159 | memset((char *)&serv_addr,0x0,sizeof(serv_addr)); 160 | serv_addr.sin_family = AF_INET; 161 | serv_addr.sin_port = htons(port); 162 | 163 | /* first assume server is dotted decimal number and call inet_addr */ 164 | if ((int)(serv_addr.sin_addr.s_addr = inet_addr(server_name)) == -1) { 165 | /* if inet_addr fails, assume server is a name and call gethostbyname to look it up */ 166 | if ((host = gethostbyname(server_name)) == NULL) { /* if gethostbyname also fails */ 167 | printf("TPM_OpenClientSocket: server name error, name %s\n", server_name); 168 | return ERR_IO; 169 | } 170 | serv_addr.sin_family = host->h_addrtype; 171 | memcpy(&serv_addr.sin_addr, host->h_addr, host->h_length); 172 | } 173 | else { 174 | /* printf("TPM_OpenClientSocket: server address: %s\n",server_name); */ 175 | } 176 | #ifdef TPM_POSIX 177 | if (connect(*sock_fd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) { 178 | printf("TPM_OpenClientsocket: Error on connect to %s:%u\n",server_name,port); 179 | printf("TPM_OpenClientsocket: client connect: error %d %s\n",errno,strerror(errno)); 180 | return ERR_IO; 181 | } 182 | #endif 183 | #ifdef TPM_WINDOWS 184 | if (connect(*sock_fd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) != 0) { 185 | printf("TPM_OpenClientsocket: Error on connect to %s:%u\n",server_name,port); 186 | printf("TPM_OpenClientsocket: client connect: error %d %s\n",errno,strerror(errno)); 187 | return ERR_IO; 188 | } 189 | #endif 190 | else { 191 | /* printf("TPM_OpenClientSocket: client connect: success\n"); */ 192 | } 193 | return 0; 194 | } 195 | 196 | /****************************************************************************/ 197 | /* */ 198 | /* Close the socket to the TPM Host emulation */ 199 | /* */ 200 | /****************************************************************************/ 201 | 202 | static uint32_t TPM_CloseClientSocket(int sock_fd) 203 | { 204 | #ifdef TPM_POSIX 205 | if (close(sock_fd) != 0) 206 | return ERR_BAD_FILE_CLOSE; 207 | #endif 208 | #ifdef TPM_WINDOWS 209 | closesocket(sock_fd); 210 | WSACleanup(); 211 | #endif 212 | return 0; 213 | } 214 | 215 | /* write buffer to socket sock_fd */ 216 | 217 | static uint32_t TPM_TransmitSocket(int sock_fd, struct tpm_buffer *tb, 218 | const char *msg) 219 | { 220 | size_t nbytes = 0; 221 | ssize_t nwritten = 0; 222 | size_t nleft = 0; 223 | unsigned int offset = 0; 224 | char mymsg[1024]; 225 | 226 | snprintf(mymsg, sizeof(mymsg), "TPM_TransmitSocket: To TPM [%s]", 227 | msg); 228 | 229 | nbytes = tb->used; 230 | 231 | showBuff(tb->buffer, mymsg); 232 | 233 | nleft = nbytes; 234 | while (nleft > 0) { 235 | #ifdef TPM_POSIX 236 | nwritten = write(sock_fd, &tb->buffer[offset], nleft); 237 | if (nwritten < 0) { /* error */ 238 | printf("TPM_TransmitSocket: write error %d\n", (int)nwritten); 239 | return ERR_IO; 240 | } 241 | #endif 242 | #ifdef TPM_WINDOWS 243 | /* cast for winsock. Unix uses void * */ 244 | nwritten = send(sock_fd, (char *)(&tb->buffer[offset]), nleft,0); 245 | if (nwritten == SOCKET_ERROR) { /* error */ 246 | printf("TPM_TransmitSocket: write error %d\n", (int)nwritten); 247 | return ERR_IO; 248 | } 249 | #endif 250 | nleft -= nwritten; 251 | offset += nwritten; 252 | } 253 | return 0; 254 | } 255 | 256 | /* read a TPM packet from socket sock_fd */ 257 | 258 | static uint32_t TPM_ReceiveSocket(int sock_fd, struct tpm_buffer *tb) 259 | { 260 | uint32_t rc = 0; 261 | uint32_t paramSize = 0; 262 | uint32_t addsize = 0; 263 | unsigned char *buffer = tb->buffer; 264 | 265 | if (TPM_LowLevel_Use_VTPM()) { 266 | addsize = sizeof(uint32_t); 267 | } 268 | 269 | /* read the tag and paramSize */ 270 | if (rc == 0) { 271 | rc = TPM_ReceiveBytes(sock_fd, buffer, addsize + TPM_U16_SIZE + TPM_U32_SIZE); 272 | } 273 | /* extract the paramSize */ 274 | if (rc == 0) { 275 | paramSize = LOAD32(buffer, addsize + TPM_PARAMSIZE_OFFSET); 276 | if (paramSize > TPM_MAX_BUFF_SIZE) { 277 | printf("TPM_ReceiveSocket: ERROR: paramSize %u greater than %u\n", 278 | paramSize, TPM_MAX_BUFF_SIZE); 279 | rc = ERR_BAD_RESP; 280 | } 281 | } 282 | /* read the rest of the packet */ 283 | if (rc == 0) { 284 | rc = TPM_ReceiveBytes(sock_fd, 285 | buffer + addsize + TPM_U16_SIZE + TPM_U32_SIZE, 286 | paramSize - (TPM_U16_SIZE + TPM_U32_SIZE)); 287 | } 288 | /* read the TPM return code from the packet */ 289 | if (rc == 0) { 290 | showBuff(buffer, "TPM_ReceiveSocket: From TPM"); 291 | rc = LOAD32(buffer, addsize + TPM_RETURN_OFFSET); 292 | tb->used = addsize + paramSize; 293 | } 294 | return rc; 295 | } 296 | 297 | /* read nbytes from socket sock_fd and put them in buffer */ 298 | 299 | static uint32_t TPM_ReceiveBytes(int sock_fd, 300 | unsigned char *buffer, 301 | size_t nbytes) 302 | { 303 | int nread = 0; 304 | int nleft = 0; 305 | 306 | nleft = nbytes; 307 | while (nleft > 0) { 308 | #ifdef TPM_POSIX 309 | nread = read(sock_fd, buffer, nleft); 310 | if (nread <= 0) { /* error */ 311 | printf("TPM_ReceiveBytes: read error %d\n", nread); 312 | return ERR_IO; 313 | } 314 | #endif 315 | #ifdef TPM_WINDOWS 316 | /* cast for winsock. Unix uses void * */ 317 | nread = recv(sock_fd, (char *)buffer, nleft, 0); 318 | if (nread == SOCKET_ERROR) { /* error */ 319 | printf("TPM_ReceiveBytes: read error %d\n", nread); 320 | return ERR_IO; 321 | } 322 | #endif 323 | else if (nread == 0) { /* EOF */ 324 | printf("TPM_ReceiveBytes: read EOF\n"); 325 | return ERR_IO; 326 | } 327 | nleft -= nread; 328 | buffer += nread; 329 | } 330 | return 0; 331 | } 332 | -------------------------------------------------------------------------------- /libtpm/tpmutil_tty.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Utility Functions */ 4 | /* Written by S. Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: tpmutil_tty.c 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | 41 | /* These are platform specific. This version uses a character device interface. 42 | 43 | */ 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #include 51 | 52 | #ifdef TPM_POSIX 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | #endif 59 | #ifdef TPM_WINDOWS 60 | #include 61 | #endif 62 | #include 63 | #include 64 | #include 65 | 66 | #ifdef USE_SERIAL_PORT 67 | #include 68 | #endif 69 | 70 | #include 71 | #include 72 | 73 | #include "tpm.h" 74 | #include "tpmfunc.h" 75 | #include "tpm_types.h" 76 | #include "tpm_constants.h" 77 | #include "tpmutil.h" 78 | #include "tpm_lowlevel.h" 79 | 80 | /* local prototypes */ 81 | static uint32_t TPM_OpenClientCharDev(int *sock_fd); 82 | static uint32_t TPM_CloseClientCharDev(int sock_fd); 83 | static uint32_t TPM_ReceiveCharDev(int sock_fd, struct tpm_buffer *tb); 84 | static uint32_t TPM_TransmitCharDev(int sock_fd, struct tpm_buffer *tb, 85 | const char *mgs); 86 | #ifdef USE_PARTIAL_READ 87 | static uint32_t TPM_ReceiveBytes(int sock_fd, 88 | unsigned char *buffer, 89 | size_t nbytes); 90 | #endif 91 | #ifdef USE_SERIAL_PORT 92 | static struct termios saved_terminos; 93 | static enum { RAW, RESET } tty_state = RESET; 94 | 95 | static uint32_t set_tty(int fd) ; 96 | static uint32_t reset_tty(int fd) ; 97 | #endif 98 | /* local variables */ 99 | #define DEFAULT_TPM_DEVICE "/dev/tpm0" 100 | #define VTPM_SOCKET "/var/vtpm/vtpm.socket" 101 | 102 | static struct tpm_transport char_transport = { 103 | .open = TPM_OpenClientCharDev, 104 | .close = TPM_CloseClientCharDev, 105 | .send = TPM_TransmitCharDev, 106 | .recv = TPM_ReceiveCharDev, 107 | }; 108 | 109 | void TPM_LowLevel_TransportCharDev_Set(void) 110 | { 111 | TPM_LowLevel_Transport_Set(&char_transport); 112 | } 113 | 114 | 115 | /****************************************************************************/ 116 | /* */ 117 | /* Open the socket to the TPM Host emulation */ 118 | /* */ 119 | /****************************************************************************/ 120 | 121 | static uint32_t 122 | TPM_OpenClientSocket_UnixIO(int *sock_fd) 123 | { 124 | struct stat _stat; 125 | if (0 == stat(VTPM_SOCKET, &_stat)) { 126 | if (S_ISSOCK(_stat.st_mode)) { 127 | *sock_fd = socket(PF_UNIX, SOCK_STREAM, 0); 128 | if (*sock_fd > 0) { 129 | struct sockaddr_un addr; 130 | addr.sun_family = AF_UNIX; 131 | strcpy(addr.sun_path, VTPM_SOCKET); 132 | if (connect(*sock_fd, 133 | (struct sockaddr *)&addr, 134 | sizeof(addr)) == 0) { 135 | return 0; 136 | } else { 137 | close(*sock_fd); 138 | *sock_fd = 0; 139 | } 140 | } 141 | } 142 | } 143 | return ERR_IO; 144 | } 145 | 146 | static uint32_t TPM_OpenClientCharDev(int *sock_fd) 147 | { 148 | char *tty_str; 149 | uint32_t rc; 150 | 151 | tty_str = getenv("TPM_DEVICE"); 152 | 153 | if (tty_str == NULL || !strcmp("unixio",tty_str)) { 154 | rc = TPM_OpenClientSocket_UnixIO(sock_fd); 155 | if (rc == 0) { 156 | return 0; 157 | } 158 | } 159 | 160 | if (tty_str == NULL) { 161 | tty_str = DEFAULT_TPM_DEVICE; 162 | } 163 | 164 | #ifndef USE_SERIAL_PORT 165 | if ((*sock_fd = open(tty_str,O_RDWR)) < 0) { 166 | printf("TPM_OpenClientCharDev: Could not open char device %s: %s\n", 167 | tty_str, 168 | strerror(errno)); 169 | return ERR_IO; 170 | } 171 | #else 172 | if ((*sock_fd = open(tty_str,O_RDWR | O_NOCTTY | O_NDELAY)) < 0) { 173 | printf("TPM_OpenClientCharDev: Could not open char device %s: %s\n", 174 | tty_str, 175 | strerror(errno)); 176 | return ERR_IO; 177 | } 178 | fcntl(*sock_fd, F_SETFL, 0); 179 | 180 | if ((rc = set_tty(*sock_fd)) > 0) { 181 | close(*sock_fd); 182 | return rc; 183 | } 184 | 185 | #endif 186 | return 0; 187 | } 188 | #ifdef USE_SERIAL_PORT 189 | /* set tty to input and output raw mode and disable software flow control */ 190 | static uint32_t set_tty(int fd) { 191 | struct termios new_terminos; 192 | 193 | if (tcgetattr(fd, &saved_terminos) < 0) { 194 | printf("set_tty: Could not get tty termios info\n"); 195 | return 1; 196 | } 197 | 198 | new_terminos = saved_terminos; 199 | /* enable */ 200 | new_terminos.c_cflag |= (CREAD| CLOCAL | CS8); 201 | 202 | /* set input to raw mode */ 203 | new_terminos.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); 204 | 205 | /* disable input processing */ 206 | new_terminos.c_iflag &= ~(PARMRK | ISTRIP | IGNCR); 207 | 208 | /* disable software flow control */ 209 | new_terminos.c_iflag &= ~(INLCR | ICRNL | IXON | IXOFF | IXANY); 210 | 211 | /* set output to raw mode */ 212 | new_terminos.c_oflag &= ~(OPOST); 213 | 214 | /* set to read one byte at a time, no timer */ 215 | new_terminos.c_cc[VMIN] = 1; 216 | new_terminos.c_cc[VTIME] = 0; 217 | 218 | if (tcsetattr(fd, TCSAFLUSH, &new_terminos) < 0) { 219 | printf("set_tty: Could not set tty termios info\n"); 220 | return 1; 221 | } 222 | tty_state = RAW; 223 | return 0; 224 | } 225 | /* retset tty */ 226 | static uint32_t reset_tty(int fd) { 227 | 228 | if (tty_state != RAW) { 229 | return 0; 230 | } 231 | if (tcsetattr(fd, TCSAFLUSH, &saved_terminos) < 0) { 232 | printf("reset_tty: Could not reset tty termios info\n"); 233 | return 1; 234 | } 235 | tty_state = RESET; 236 | return 0; 237 | } 238 | #endif 239 | /****************************************************************************/ 240 | /* */ 241 | /* Close the socket to the TPM Host emulation */ 242 | /* */ 243 | /****************************************************************************/ 244 | 245 | static uint32_t TPM_CloseClientCharDev(int sock_fd) 246 | { 247 | 248 | #ifdef USE_SERIAL_PORT 249 | reset_tty(sock_fd); 250 | #endif 251 | close(sock_fd); 252 | return 0; 253 | } 254 | 255 | /* write buffer to socket sock_fd */ 256 | 257 | static uint32_t TPM_TransmitCharDev(int sock_fd, struct tpm_buffer *tb, 258 | const char *msg) 259 | { 260 | uint32_t nbytes = 0; 261 | ssize_t nwritten = 0; 262 | size_t nleft = 0; 263 | unsigned int offset = 0; 264 | uint32_t ret; 265 | char mymsg[1024]; 266 | 267 | snprintf(mymsg, sizeof(mymsg), "TPM_TransmitCharDev: To TPM [%s]", 268 | msg); 269 | 270 | ret = tpm_buffer_load32(tb, TPM_PARAMSIZE_OFFSET, &nbytes); 271 | if ((ret & ERR_MASK)) { 272 | return ret; 273 | } 274 | showBuff(tb->buffer, mymsg); 275 | 276 | nleft = nbytes; 277 | while (nleft > 0) { 278 | nwritten = write(sock_fd, &tb->buffer[offset], nleft); 279 | if (nwritten < 0) { /* error */ 280 | printf("TPM_TransmitCharDev: write error %d\n", (int)nwritten); 281 | return nwritten; 282 | } 283 | nleft -= nwritten; 284 | offset += nwritten; 285 | } 286 | return 0; 287 | } 288 | 289 | /* read a TPM packet from socket sock_fd */ 290 | 291 | static uint32_t 292 | TPM_ReceiveCharDev(int sock_fd, struct tpm_buffer *tb) 293 | { 294 | uint32_t rc = 0; 295 | uint32_t paramSize = 0; 296 | unsigned char *buffer = tb->buffer; 297 | 298 | #ifndef USE_PARTIAL_READ 299 | /* read the whole packet */ 300 | if (rc == 0) { 301 | int nread; 302 | nread = read(sock_fd, tb->buffer, tb->size); 303 | if (nread < 0) { 304 | rc = ERR_IO; 305 | } else { 306 | tb->used = nread; 307 | } 308 | } 309 | #endif 310 | 311 | #ifdef USE_PARTIAL_READ 312 | /* read the tag and paramSize */ 313 | if (rc == 0) { 314 | rc = TPM_ReceiveBytes(sock_fd, buffer, TPM_U16_SIZE + TPM_U32_SIZE); 315 | } 316 | #endif 317 | /* extract the paramSize */ 318 | if (rc == 0) { 319 | paramSize = LOAD32(buffer, TPM_PARAMSIZE_OFFSET); 320 | if (paramSize > TPM_MAX_BUFF_SIZE) { 321 | printf("TPM_ReceiveCharDev: paramSize %u greater than %u\n", 322 | paramSize, TPM_MAX_BUFF_SIZE); 323 | rc = ERR_BAD_RESP; 324 | } 325 | } 326 | #ifdef USE_PARTIAL_READ 327 | /* read the rest of the packet */ 328 | if (rc == 0) { 329 | rc = TPM_ReceiveBytes(sock_fd, 330 | buffer + TPM_U16_SIZE + TPM_U32_SIZE, 331 | paramSize - (TPM_U16_SIZE + TPM_U32_SIZE)); 332 | } 333 | #endif 334 | /* read the TPM return code from the packet */ 335 | if (rc == 0) { 336 | showBuff(buffer, "TPM_ReceiveCharDev: From TPM"); 337 | tb->used = paramSize; 338 | tpm_buffer_load32(tb, TPM_RETURN_OFFSET, &rc); 339 | } 340 | return rc; 341 | } 342 | 343 | #ifdef USE_PARTIAL_READ 344 | /* read nbytes from socket sock_fd and put them in buffer */ 345 | static 346 | uint32_t TPM_ReceiveBytes(int sock_fd, 347 | unsigned char *buffer, 348 | size_t nbytes) 349 | { 350 | int nread = 0; 351 | int nleft = 0; 352 | 353 | nleft = nbytes; 354 | while (nleft > 0) { 355 | nread = read(sock_fd, buffer, nleft); 356 | if (nread <= 0) { /* error */ 357 | printf("TPM_ReceiveBytes: read error %d\n", nread); 358 | return ERR_IO; 359 | } 360 | else if (nread == 0) { /* EOF */ 361 | printf("TPM_ReceiveBytes: read EOF\n"); 362 | return ERR_IO; 363 | } 364 | nleft -= nread; 365 | buffer += nread; 366 | } 367 | return 0; 368 | } 369 | #endif 370 | -------------------------------------------------------------------------------- /libtpm/tpmutil_unixio.c: -------------------------------------------------------------------------------- 1 | /********************************************************************************/ 2 | /* */ 3 | /* TPM Utility Functions */ 4 | /* Written by Kenneth Goldman, Stefan Berger */ 5 | /* IBM Thomas J. Watson Research Center */ 6 | /* $Id: tpmutil_unixio.c 4702 2013-01-03 21:26:29Z kgoldman $ */ 7 | /* */ 8 | /* (c) Copyright IBM Corporation 2006, 2010. */ 9 | /* */ 10 | /* All rights reserved. */ 11 | /* */ 12 | /* Redistribution and use in source and binary forms, with or without */ 13 | /* modification, are permitted provided that the following conditions are */ 14 | /* met: */ 15 | /* */ 16 | /* Redistributions of source code must retain the above copyright notice, */ 17 | /* this list of conditions and the following disclaimer. */ 18 | /* */ 19 | /* Redistributions in binary form must reproduce the above copyright */ 20 | /* notice, this list of conditions and the following disclaimer in the */ 21 | /* documentation and/or other materials provided with the distribution. */ 22 | /* */ 23 | /* Neither the names of the IBM Corporation nor the names of its */ 24 | /* contributors may be used to endorse or promote products derived from */ 25 | /* this software without specific prior written permission. */ 26 | /* */ 27 | /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ 28 | /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ 29 | /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ 30 | /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ 31 | /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 32 | /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 33 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ 34 | /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ 35 | /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 36 | /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ 37 | /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 38 | /********************************************************************************/ 39 | 40 | 41 | /* These are platform specific. This version uses a UnixIO socket interface. 42 | 43 | Environment variables are: 44 | 45 | TPM_UNIXIO_PATH - the path to the UNIX IO socket 46 | */ 47 | 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | 54 | #include 55 | 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | #include 62 | 63 | #include "tpm.h" 64 | #include "tpmfunc.h" 65 | #include "tpm_types.h" 66 | #include "tpm_constants.h" 67 | #include "tpmutil.h" 68 | #include "tpm_lowlevel.h" 69 | 70 | /* local prototypes */ 71 | static uint32_t TPM_OpenClientSocket_UnixIO(int *sock_fd); 72 | static uint32_t TPM_CloseClientSocket(int sock_fd); 73 | static uint32_t TPM_TransmitSocket(int sock_fd, struct tpm_buffer *tb, 74 | const char *msg); 75 | static uint32_t TPM_ReceiveSocket(int sock_fd, struct tpm_buffer *tb); 76 | static uint32_t TPM_ReceiveBytes(int sock_fd, 77 | unsigned char *buffer, 78 | size_t nbytes); 79 | 80 | 81 | /* local variables */ 82 | static struct tpm_transport unixio_transport = { 83 | .open = TPM_OpenClientSocket_UnixIO, 84 | .close = TPM_CloseClientSocket, 85 | .send = TPM_TransmitSocket, 86 | .recv = TPM_ReceiveSocket, 87 | }; 88 | 89 | void TPM_LowLevel_TransportUnixIO_Set(void) 90 | { 91 | TPM_LowLevel_Transport_Set(&unixio_transport); 92 | } 93 | 94 | /****************************************************************************/ 95 | /* */ 96 | /* Open the socket to the TPM Host emulation */ 97 | /* */ 98 | /****************************************************************************/ 99 | 100 | static uint32_t TPM_OpenClientSocket_UnixIO(int *sock_fd) 101 | { 102 | struct stat _stat; 103 | char *unixio_path; 104 | 105 | unixio_path = getenv("TPM_UNIXIO_PATH"); 106 | if (unixio_path == NULL) { 107 | printf("TPM_OpenClientSocket: Error, TPM_UNIXIO_PATH environment variable not set\n"); 108 | return ERR_IO; 109 | } 110 | 111 | if (0 == stat(unixio_path, &_stat)) { 112 | if (S_ISSOCK(_stat.st_mode)) { 113 | *sock_fd = socket(PF_UNIX, SOCK_STREAM, 0); 114 | if (*sock_fd > 0) { 115 | struct sockaddr_un addr; 116 | addr.sun_family = AF_UNIX; 117 | strcpy(addr.sun_path, unixio_path); 118 | if (connect(*sock_fd, 119 | (struct sockaddr *)&addr, 120 | sizeof(addr)) == 0) { 121 | return 0; 122 | } else { 123 | close(*sock_fd); 124 | *sock_fd = 0; 125 | } 126 | } 127 | } 128 | } 129 | return ERR_IO; 130 | } 131 | 132 | /****************************************************************************/ 133 | /* */ 134 | /* Close the socket to the TPM Host emulation */ 135 | /* */ 136 | /****************************************************************************/ 137 | 138 | static uint32_t TPM_CloseClientSocket(int sock_fd) 139 | { 140 | close(sock_fd); 141 | return 0; 142 | } 143 | 144 | /* write buffer to socket sock_fd */ 145 | 146 | static uint32_t TPM_TransmitSocket(int sock_fd, struct tpm_buffer *tb, 147 | const char *msg) 148 | { 149 | size_t nbytes = 0; 150 | ssize_t nwritten = 0; 151 | size_t nleft = 0; 152 | unsigned int offset = 0; 153 | char mymsg[1024]; 154 | 155 | snprintf(mymsg, sizeof(mymsg), "TPM_TransmitSocket: To TPM [%s]", 156 | msg); 157 | 158 | nbytes = tb->used; 159 | 160 | showBuff(tb->buffer, mymsg); 161 | 162 | nleft = nbytes; 163 | while (nleft > 0) { 164 | nwritten = write(sock_fd, &tb->buffer[offset], nleft); 165 | if (nwritten < 0) { /* error */ 166 | printf("TPM_TransmitSocket: write error %d\n", (int)nwritten); 167 | return nwritten; 168 | } 169 | nleft -= nwritten; 170 | offset += nwritten; 171 | } 172 | return 0; 173 | } 174 | 175 | /* read a TPM packet from socket sock_fd */ 176 | 177 | static uint32_t TPM_ReceiveSocket(int sock_fd, struct tpm_buffer *tb) 178 | { 179 | uint32_t rc = 0; 180 | uint32_t paramSize = 0; 181 | uint32_t addsize = 0; 182 | unsigned char *buffer = tb->buffer; 183 | 184 | if (TPM_LowLevel_Use_VTPM()) { 185 | addsize = sizeof(uint32_t); 186 | } 187 | 188 | /* read the tag and paramSize */ 189 | if (rc == 0) { 190 | rc = TPM_ReceiveBytes(sock_fd, buffer, addsize + TPM_U16_SIZE + TPM_U32_SIZE); 191 | } 192 | /* extract the paramSize */ 193 | if (rc == 0) { 194 | paramSize = LOAD32(buffer, addsize + TPM_PARAMSIZE_OFFSET); 195 | if (paramSize > TPM_MAX_BUFF_SIZE) { 196 | printf("TPM_ReceiveSocket: ERROR: paramSize %u greater than %u\n", 197 | paramSize, TPM_MAX_BUFF_SIZE); 198 | rc = ERR_BAD_RESP; 199 | } 200 | } 201 | /* read the rest of the packet */ 202 | if (rc == 0) { 203 | rc = TPM_ReceiveBytes(sock_fd, 204 | buffer + addsize + TPM_U16_SIZE + TPM_U32_SIZE, 205 | paramSize - (TPM_U16_SIZE + TPM_U32_SIZE)); 206 | } 207 | /* read the TPM return code from the packet */ 208 | if (rc == 0) { 209 | showBuff(buffer, "TPM_ReceiveSocket: From TPM"); 210 | rc = LOAD32(buffer, addsize + TPM_RETURN_OFFSET); 211 | tb->used = addsize + paramSize; 212 | } 213 | return rc; 214 | } 215 | 216 | /* read nbytes from socket sock_fd and put them in buffer */ 217 | 218 | static uint32_t TPM_ReceiveBytes(int sock_fd, 219 | unsigned char *buffer, 220 | size_t nbytes) 221 | { 222 | int nread = 0; 223 | int nleft = 0; 224 | 225 | nleft = nbytes; 226 | while (nleft > 0) { 227 | nread = read(sock_fd, buffer, nleft); 228 | if (nread <= 0) { /* error */ 229 | printf("TPM_ReceiveBytes: read error %d\n", nread); 230 | return ERR_IO; 231 | } 232 | else if (nread == 0) { /* EOF */ 233 | printf("TPM_ReceiveBytes: read EOF\n"); 234 | return ERR_IO; 235 | } 236 | nleft -= nread; 237 | buffer += nread; 238 | } 239 | return 0; 240 | } 241 | -------------------------------------------------------------------------------- /plymouth-unsealtotp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * sealtotp - generate a TOTP secret and seal it to the local TPM 3 | * 4 | * Copyright 2015 Matthew Garrett 5 | * 6 | * Portions derived from unsealfile.c by J. Kravitz and Copyright (C) 2004 IBM 7 | * Corporation 8 | * 9 | */ 10 | 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "tpmfunc.h" 20 | #include 21 | #include 22 | #include 23 | 24 | #define keylen 20 25 | char key[keylen]; 26 | static char efivarfs[] = "/sys/firmware/efi/efivars"; 27 | 28 | static ply_boot_client_t *ply_client; 29 | static ply_event_loop_t *ply_loop; 30 | 31 | static void on_failure(void* dummy) 32 | { 33 | ply_event_loop_exit(ply_loop, 0); 34 | } 35 | 36 | static void on_disconnect(void* dummy) 37 | { 38 | ply_event_loop_exit(ply_loop, 0); 39 | } 40 | 41 | static void display_totp() { 42 | int ret; 43 | char totp[7]; 44 | 45 | ret = oath_totp_generate(key, keylen, time(NULL), 30, 0, 6, totp); 46 | if (ret != 0) { 47 | fprintf(stderr, "Error generating totp value\n"); 48 | exit(-1); 49 | } 50 | ply_boot_client_tell_daemon_to_display_message (ply_client, 51 | totp, NULL, 52 | (ply_boot_client_response_handler_t) on_failure, NULL); 53 | } 54 | 55 | static void on_timeout(void* dummy) 56 | { 57 | time_t t = time(NULL); 58 | time_t delay; 59 | 60 | display_totp(); 61 | delay = 30 - (t % 30); 62 | ply_event_loop_watch_for_timeout(ply_loop, delay, on_timeout, NULL); 63 | } 64 | 65 | int main(int argc, char *argv[]) 66 | { 67 | int ret; 68 | struct stat sbuf; 69 | uint32_t parhandle; /* handle of parent key */ 70 | unsigned char blob[4096]; /* resulting sealed blob */ 71 | unsigned int bloblen = 322; /* blob length */ 72 | unsigned char passptr1[20] = {0}; 73 | int fd, outlen, i; 74 | time_t t, delay; 75 | 76 | parhandle = 0x40000000; 77 | 78 | ret = TPM_NV_ReadValue(0x10004d47, 0, 322, blob, &bloblen, NULL); 79 | if (ret != 0) { 80 | for (i=1; i 5 | * 6 | * Portions derived from unsealfile.c by J. Kravitz and Copyright (C) 2004 IBM 7 | * Corporation 8 | * 9 | */ 10 | 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "tpmfunc.h" 20 | #include 21 | 22 | #define keylen 20 23 | char key[keylen]; 24 | const char efivarfs[] = "/sys/firmware/efi/efivars/"; 25 | 26 | int main(int argc, char *argv[]) 27 | { 28 | int ret; 29 | struct stat sbuf; 30 | uint32_t parhandle; /* handle of parent key */ 31 | unsigned char blob[4096]; /* resulting sealed blob */ 32 | unsigned int bloblen = 322; /* blob length */ 33 | unsigned char passptr1[20] = {0}; 34 | int fd, outlen, i; 35 | char totp[7]; 36 | parhandle = 0x40000000; 37 | 38 | ret = TPM_NV_ReadValue(0x10004d47, 0, 322, blob, &bloblen, NULL); 39 | if (ret) { 40 | for (i=1; i